Fixed mem leak caused by not releasing pad & wiimote plugin when shutdown
Fixed main frame crash after shutdown git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4755 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
97779ea295
commit
151ff28ab7
|
@ -213,19 +213,15 @@ void Stop() // - Hammertime!
|
||||||
PowerPC::Stop();
|
PowerPC::Stop();
|
||||||
CCPU::StepOpcode(); // Kick it if it's waiting (code stepping wait loop)
|
CCPU::StepOpcode(); // Kick it if it's waiting (code stepping wait loop)
|
||||||
|
|
||||||
// Wait until the CPU finishes exiting the main run loop
|
|
||||||
cpuRunloopQuit.Wait();
|
|
||||||
cpuRunloopQuit.Shutdown();
|
|
||||||
// At this point, we must be out of the CPU:s runloop.
|
|
||||||
|
|
||||||
// Stop audio thread.
|
|
||||||
CPluginManager::GetInstance().GetDSP()->DSP_StopSoundStream();
|
|
||||||
|
|
||||||
// If dual core mode, the CPU thread should immediately exit here.
|
// If dual core mode, the CPU thread should immediately exit here.
|
||||||
if (_CoreParameter.bCPUThread) {
|
if (_CoreParameter.bCPUThread) {
|
||||||
NOTICE_LOG(CONSOLE, "%s", StopMessage(true, "Wait for Video Loop to exit ...").c_str());
|
NOTICE_LOG(CONSOLE, "%s", StopMessage(true, "Wait for Video Loop to exit ...").c_str());
|
||||||
CPluginManager::GetInstance().GetVideo()->Video_ExitLoop();
|
CPluginManager::GetInstance().GetVideo()->Video_ExitLoop();
|
||||||
}
|
}
|
||||||
|
// Wait until the CPU finishes exiting the main run loop
|
||||||
|
cpuRunloopQuit.Wait();
|
||||||
|
cpuRunloopQuit.Shutdown();
|
||||||
|
// At this point, we must be out of the CPU:s runloop.
|
||||||
|
|
||||||
// Video_EnterLoop() should now exit so that EmuThread() will continue concurrently with the rest
|
// Video_EnterLoop() should now exit so that EmuThread() will continue concurrently with the rest
|
||||||
// of the commands in this function. We no longer rely on Postmessage.
|
// of the commands in this function. We no longer rely on Postmessage.
|
||||||
|
@ -296,7 +292,6 @@ THREAD_RETURN CpuThread(void *pArg)
|
||||||
|
|
||||||
// Enter CPU run loop. When we leave it - we are done.
|
// Enter CPU run loop. When we leave it - we are done.
|
||||||
CCPU::Run();
|
CCPU::Run();
|
||||||
cpuRunloopQuit.Set();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -370,29 +365,12 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
|
|
||||||
Plugins.GetDSP()->Initialize((void *)&dspInit);
|
Plugins.GetDSP()->Initialize((void *)&dspInit);
|
||||||
|
|
||||||
// Load and Init PadPlugin
|
|
||||||
for (int i = 0; i < MAXPADS; i++)
|
|
||||||
{
|
|
||||||
SPADInitialize PADInitialize;
|
SPADInitialize PADInitialize;
|
||||||
PADInitialize.hWnd = g_pWindowHandle;
|
PADInitialize.hWnd = g_pWindowHandle;
|
||||||
PADInitialize.pLog = Callback_PADLog;
|
PADInitialize.pLog = Callback_PADLog;
|
||||||
PADInitialize.padNumber = i;
|
|
||||||
// This is may be needed to avoid a SDL problem
|
// This is may be needed to avoid a SDL problem
|
||||||
//Plugins.FreeWiimote();
|
//Plugins.FreeWiimote();
|
||||||
// Check if we should init the plugin
|
Plugins.GetPad(0)->Initialize(&PADInitialize);
|
||||||
if (Plugins.OkayToInitPlugin(i))
|
|
||||||
{
|
|
||||||
Plugins.GetPad(i)->Initialize(&PADInitialize);
|
|
||||||
|
|
||||||
// Check if joypad open failed, in that case try again
|
|
||||||
if (PADInitialize.padNumber == -1)
|
|
||||||
{
|
|
||||||
Plugins.GetPad(i)->Shutdown();
|
|
||||||
Plugins.FreePad(i);
|
|
||||||
Plugins.GetPad(i)->Initialize(&PADInitialize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load and Init WiimotePlugin - only if we are booting in wii mode
|
// Load and Init WiimotePlugin - only if we are booting in wii mode
|
||||||
if (_CoreParameter.bWii)
|
if (_CoreParameter.bWii)
|
||||||
|
@ -459,7 +437,6 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
// then we lose the powerdown check. ... unless powerdown sends a message :P
|
// then we lose the powerdown check. ... unless powerdown sends a message :P
|
||||||
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
|
while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
|
||||||
{
|
{
|
||||||
Host_UpdateMainFrame();
|
|
||||||
if (Callback_PeekMessages)
|
if (Callback_PeekMessages)
|
||||||
Callback_PeekMessages();
|
Callback_PeekMessages();
|
||||||
Common::SleepCurrentThread(20);
|
Common::SleepCurrentThread(20);
|
||||||
|
@ -507,6 +484,8 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
// We have now exited the Video Loop and will shut down
|
// We have now exited the Video Loop and will shut down
|
||||||
|
|
||||||
g_bHwInit = false;
|
g_bHwInit = false;
|
||||||
|
// Stop audio thread.
|
||||||
|
Plugins.GetDSP()->DSP_StopSoundStream();
|
||||||
|
|
||||||
WARN_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down plugins").c_str());
|
WARN_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down plugins").c_str());
|
||||||
Plugins.ShutdownVideoPlugin();
|
Plugins.ShutdownVideoPlugin();
|
||||||
|
@ -521,8 +500,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
||||||
NOTICE_LOG(CONSOLE, "Stop [Main Thread]\t\t---- Shutdown complete ----");
|
NOTICE_LOG(CONSOLE, "Stop [Main Thread]\t\t---- Shutdown complete ----");
|
||||||
|
|
||||||
g_bStopping = false;
|
g_bStopping = false;
|
||||||
|
cpuRunloopQuit.Set();
|
||||||
Host_UpdateMainFrame();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include "IniFile.h"
|
#include "IniFile.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define MAXPADS 4
|
#define MAXPADS 1
|
||||||
#define MAXWIIMOTES 1
|
#define MAXWIIMOTES 1
|
||||||
|
|
||||||
struct SCoreStartupParameter
|
struct SCoreStartupParameter
|
||||||
|
|
|
@ -144,7 +144,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength)
|
||||||
DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: CMD 10, %02x (READ STATUS&SWITCHES)", ptr(1));
|
DEBUG_LOG(AMBASEBOARDDEBUG, "GC-AM: CMD 10, %02x (READ STATUS&SWITCHES)", ptr(1));
|
||||||
SPADStatus PadStatus;
|
SPADStatus PadStatus;
|
||||||
memset(&PadStatus, 0 ,sizeof(PadStatus));
|
memset(&PadStatus, 0 ,sizeof(PadStatus));
|
||||||
CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber)
|
CPluginManager::GetInstance().GetPad(0)
|
||||||
->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
|
->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
|
||||||
res[resp++] = 0x10;
|
res[resp++] = 0x10;
|
||||||
res[resp++] = 0x2;
|
res[resp++] = 0x2;
|
||||||
|
@ -312,7 +312,7 @@ int CSIDevice_AMBaseboard::RunBuffer(u8* _pBuffer, int _iLength)
|
||||||
for (i=0; i<nr_players; ++i)
|
for (i=0; i<nr_players; ++i)
|
||||||
{
|
{
|
||||||
SPADStatus PadStatus;
|
SPADStatus PadStatus;
|
||||||
CPluginManager::GetInstance().GetPad(i)
|
CPluginManager::GetInstance().GetPad(0)
|
||||||
->PAD_GetStatus(i, &PadStatus);
|
->PAD_GetStatus(i, &PadStatus);
|
||||||
unsigned char player_data[2] = {0,0};
|
unsigned char player_data[2] = {0,0};
|
||||||
if (PadStatus.button & PAD_BUTTON_START)
|
if (PadStatus.button & PAD_BUTTON_START)
|
||||||
|
|
|
@ -128,7 +128,7 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||||
{
|
{
|
||||||
SPADStatus PadStatus;
|
SPADStatus PadStatus;
|
||||||
memset(&PadStatus, 0, sizeof(PadStatus));
|
memset(&PadStatus, 0, sizeof(PadStatus));
|
||||||
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
|
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(0);
|
||||||
pad->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
|
pad->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
|
||||||
|
|
||||||
#if defined(HAVE_SFML) && HAVE_SFML
|
#if defined(HAVE_SFML) && HAVE_SFML
|
||||||
|
@ -257,7 +257,7 @@ bool CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
|
||||||
// SendCommand
|
// SendCommand
|
||||||
void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll)
|
void CSIDevice_GCController::SendCommand(u32 _Cmd, u8 _Poll)
|
||||||
{
|
{
|
||||||
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
|
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(0);
|
||||||
UCommand command(_Cmd);
|
UCommand command(_Cmd);
|
||||||
|
|
||||||
switch (command.Command)
|
switch (command.Command)
|
||||||
|
|
|
@ -76,17 +76,21 @@ CPluginManager::~CPluginManager()
|
||||||
|
|
||||||
for (int i = 0; i < MAXPADS; i++)
|
for (int i = 0; i < MAXPADS; i++)
|
||||||
{
|
{
|
||||||
if (m_pad[i] && (OkayToInitPlugin(i) == -1))
|
if (m_pad[i])
|
||||||
{
|
{
|
||||||
INFO_LOG(CONSOLE, "Delete: %i\n", i);
|
|
||||||
delete m_pad[i];
|
delete m_pad[i];
|
||||||
}
|
|
||||||
m_pad[i] = NULL;
|
m_pad[i] = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAXWIIMOTES; i++)
|
for (int i = 0; i < MAXWIIMOTES; i++)
|
||||||
|
{
|
||||||
if (m_wiimote[i])
|
if (m_wiimote[i])
|
||||||
|
{
|
||||||
delete m_wiimote[i];
|
delete m_wiimote[i];
|
||||||
|
m_wiimote[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete m_video;
|
delete m_video;
|
||||||
}
|
}
|
||||||
|
@ -139,15 +143,18 @@ bool CPluginManager::InitPlugins()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init wiimote
|
// Init wiimote
|
||||||
if (m_params->bWii) {
|
if (m_params->bWii)
|
||||||
for (int i = 0; i < MAXWIIMOTES; i++) {
|
{
|
||||||
|
for (int i = 0; i < MAXWIIMOTES; i++)
|
||||||
|
{
|
||||||
if (!m_params->m_strWiimotePlugin[i].empty())
|
if (!m_params->m_strWiimotePlugin[i].empty())
|
||||||
GetWiimote(i);
|
GetWiimote(i);
|
||||||
|
|
||||||
if (m_wiimote[i] != NULL)
|
if (m_wiimote[i] != NULL)
|
||||||
wiimote = true;
|
wiimote = true;
|
||||||
}
|
}
|
||||||
if (!wiimote) {
|
if (!wiimote)
|
||||||
|
{
|
||||||
PanicAlert("Can't init any Wiimote Plugins");
|
PanicAlert("Can't init any Wiimote Plugins");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -161,13 +168,13 @@ bool CPluginManager::InitPlugins()
|
||||||
// for an explanation about the current LoadLibrary() and FreeLibrary() behavior.
|
// for an explanation about the current LoadLibrary() and FreeLibrary() behavior.
|
||||||
void CPluginManager::ShutdownPlugins()
|
void CPluginManager::ShutdownPlugins()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAXPADS; i++) {
|
for (int i = 0; i < MAXPADS; i++)
|
||||||
|
{
|
||||||
if (m_pad[i])
|
if (m_pad[i])
|
||||||
{
|
{
|
||||||
m_pad[i]->Shutdown();
|
m_pad[i]->Shutdown();
|
||||||
//delete m_pad[i];
|
FreePad(i);
|
||||||
}
|
}
|
||||||
//m_pad[i] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MAXWIIMOTES; i++)
|
for (int i = 0; i < MAXWIIMOTES; i++)
|
||||||
|
@ -175,9 +182,8 @@ void CPluginManager::ShutdownPlugins()
|
||||||
if (m_wiimote[i])
|
if (m_wiimote[i])
|
||||||
{
|
{
|
||||||
m_wiimote[i]->Shutdown();
|
m_wiimote[i]->Shutdown();
|
||||||
//delete m_wiimote[i];
|
FreeWiimote(i);
|
||||||
}
|
}
|
||||||
//m_wiimote[i] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_dsp)
|
if (m_dsp)
|
||||||
|
@ -224,7 +230,9 @@ CPluginInfo::CPluginInfo(const char *_rFilename)
|
||||||
PanicAlert("Could not get info about plugin %s", _rFilename);
|
PanicAlert("Could not get info about plugin %s", _rFilename);
|
||||||
// We are now done with this plugin and will call FreeLibrary()
|
// We are now done with this plugin and will call FreeLibrary()
|
||||||
delete plugin;
|
delete plugin;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
WARN_LOG(CONSOLE, "PluginInfo: %s is not a valid Dolphin plugin. Ignoring.", _rFilename);
|
WARN_LOG(CONSOLE, "PluginInfo: %s is not a valid Dolphin plugin. Ignoring.", _rFilename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,19 +316,6 @@ void *CPluginManager::LoadPlugin(const char *_rFilename, int Number)
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the plugin has already been initialized. If so, return the Id of
|
|
||||||
the duplicate pad so we can point the new m_pad[] to that */
|
|
||||||
int CPluginManager::OkayToInitPlugin(int Plugin)
|
|
||||||
{
|
|
||||||
// Compare it to the earlier plugins
|
|
||||||
for (int i = 0; i < Plugin; i++)
|
|
||||||
if (m_params->m_strPadPlugin[Plugin] == m_params->m_strPadPlugin[i])
|
|
||||||
return i;
|
|
||||||
|
|
||||||
// No there is no duplicate plugin
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLUGIN_GLOBALS* CPluginManager::GetGlobals()
|
PLUGIN_GLOBALS* CPluginManager::GetGlobals()
|
||||||
{
|
{
|
||||||
return m_PluginGlobals;
|
return m_PluginGlobals;
|
||||||
|
@ -386,15 +381,8 @@ Common::PluginPAD *CPluginManager::GetPad(int controller)
|
||||||
if (m_pad[controller]->GetFilename() == m_params->m_strPadPlugin[controller])
|
if (m_pad[controller]->GetFilename() == m_params->m_strPadPlugin[controller])
|
||||||
return m_pad[controller];
|
return m_pad[controller];
|
||||||
|
|
||||||
// Else do this
|
// Else load a new plugin
|
||||||
if (OkayToInitPlugin(controller) == -1) {
|
m_pad[controller] = (Common::PluginPAD*)LoadPlugin(m_params->m_strPadPlugin[controller].c_str());
|
||||||
m_pad[controller] = (Common::PluginPAD*)LoadPlugin(m_params->m_strPadPlugin[controller].c_str(), controller);
|
|
||||||
INFO_LOG(CONSOLE, "LoadPlugin: %i", controller);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
INFO_LOG(CONSOLE, "Pointed: %i to %i", controller, OkayToInitPlugin(controller));
|
|
||||||
m_pad[controller] = m_pad[OkayToInitPlugin(controller)];
|
|
||||||
}
|
|
||||||
return m_pad[controller];
|
return m_pad[controller];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +446,8 @@ void CPluginManager::FreeDSP()
|
||||||
|
|
||||||
void CPluginManager::FreePad(u32 Pad)
|
void CPluginManager::FreePad(u32 Pad)
|
||||||
{
|
{
|
||||||
if (Pad < MAXPADS) {
|
if (Pad < MAXPADS)
|
||||||
|
{
|
||||||
delete m_pad[Pad];
|
delete m_pad[Pad];
|
||||||
m_pad[Pad] = NULL;
|
m_pad[Pad] = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,6 @@ public:
|
||||||
bool InitPlugins();
|
bool InitPlugins();
|
||||||
void ShutdownPlugins();
|
void ShutdownPlugins();
|
||||||
void ShutdownVideoPlugin();
|
void ShutdownVideoPlugin();
|
||||||
int OkayToInitPlugin(int Plugin);
|
|
||||||
void ScanForPlugins();
|
void ScanForPlugins();
|
||||||
void OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type);
|
void OpenConfig(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type);
|
||||||
void OpenDebug(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type, bool Show);
|
void OpenDebug(void* _Parent, const char *_rFilename, PLUGIN_TYPE Type, bool Show);
|
||||||
|
|
|
@ -133,11 +133,6 @@ inline void WriteHigh(volatile u32& _reg, u16 highbits) {Common::AtomicStore(_re
|
||||||
inline u16 ReadLow (u32 _reg) {return (u16)(_reg & 0xFFFF);}
|
inline u16 ReadLow (u32 _reg) {return (u16)(_reg & 0xFFFF);}
|
||||||
inline u16 ReadHigh (u32 _reg) {return (u16)(_reg >> 16);}
|
inline u16 ReadHigh (u32 _reg) {return (u16)(_reg >> 16);}
|
||||||
|
|
||||||
void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate)
|
|
||||||
{
|
|
||||||
UpdateInterrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
m_CPStatusReg.Hex = 0;
|
m_CPStatusReg.Hex = 0;
|
||||||
|
@ -161,7 +156,7 @@ void Init()
|
||||||
|
|
||||||
s_fifoIdleEvent.Init();
|
s_fifoIdleEvent.Init();
|
||||||
|
|
||||||
et_UpdateInterrupts = g_VideoInitialize.pRegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
|
// et_UpdateInterrupts = g_VideoInitialize.pRegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
|
@ -187,7 +182,7 @@ void Read16(u16& _rReturnValue, const u32 _Address)
|
||||||
m_CPStatusReg.ReadIdle = fifo.CPReadIdle; // This seems not necessary though
|
m_CPStatusReg.ReadIdle = fifo.CPReadIdle; // This seems not necessary though
|
||||||
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
|
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
|
||||||
// Clear on Read
|
// Clear on Read
|
||||||
g_VideoInitialize.pSetInterrupt(INT_CAUSE_CP, false);
|
UpdateInterrupts(false);
|
||||||
|
|
||||||
_rReturnValue = m_CPStatusReg.Hex;
|
_rReturnValue = m_CPStatusReg.Hex;
|
||||||
|
|
||||||
|
@ -358,14 +353,22 @@ void Write16(const u16 _Value, const u32 _Address)
|
||||||
{
|
{
|
||||||
// Instant Breakpoint and Interrupt, since we haven't implemented accurate BP on dual core
|
// Instant Breakpoint and Interrupt, since we haven't implemented accurate BP on dual core
|
||||||
// Most likely the Read thread has already exceeded BP here, but it seems we are still cool
|
// Most likely the Read thread has already exceeded BP here, but it seems we are still cool
|
||||||
Common::AtomicStore(fifo.bFF_Breakpoint, tmpCtrl.BPEnable && tmpCtrl.CPIntEnable && tmpCtrl.GPReadEnable);
|
if (tmpCtrl.BPEnable && tmpCtrl.CPIntEnable && tmpCtrl.GPReadEnable && tmpCtrl.GPLinkEnable)
|
||||||
UpdateInterrupts();
|
{
|
||||||
|
Common::AtomicStore(fifo.bFF_Breakpoint, 1);
|
||||||
|
UpdateInterrupts(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Common::AtomicStore(fifo.bFF_Breakpoint, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// fifo.bFF_BPEnable is only used in single core
|
// fifo.bFF_BPEnable is only used in single core
|
||||||
Common::AtomicStore(fifo.bFF_BPEnable, tmpCtrl.BPEnable && tmpCtrl.CPIntEnable && tmpCtrl.GPReadEnable);
|
Common::AtomicStore(fifo.bFF_BPEnable, tmpCtrl.BPEnable && tmpCtrl.CPIntEnable && tmpCtrl.GPReadEnable && tmpCtrl.GPLinkEnable);
|
||||||
if (!tmpCtrl.BPEnable || !tmpCtrl.CPIntEnable || !tmpCtrl.GPReadEnable)
|
if (!tmpCtrl.BPEnable || !tmpCtrl.CPIntEnable || !tmpCtrl.GPReadEnable || !tmpCtrl.GPLinkEnable)
|
||||||
Common::AtomicStore(fifo.bFF_Breakpoint, 0);
|
Common::AtomicStore(fifo.bFF_Breakpoint, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,7 +611,7 @@ void CatchUpGPU()
|
||||||
{
|
{
|
||||||
//_assert_msg_(POWERPC,0,"BP: %08x",fifo.CPBreakpoint);
|
//_assert_msg_(POWERPC,0,"BP: %08x",fifo.CPBreakpoint);
|
||||||
fifo.bFF_Breakpoint = 1;
|
fifo.bFF_Breakpoint = 1;
|
||||||
UpdateInterrupts();
|
UpdateInterrupts(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -669,17 +672,24 @@ void UpdateFifoRegister()
|
||||||
CatchUpGPU();
|
CatchUpGPU();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateInterrupts()
|
void UpdateInterrupts(bool active)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(COMMANDPROCESSOR, "Fifo Breakpoint Interrupt triggered");
|
DEBUG_LOG(COMMANDPROCESSOR, "Fifo Breakpoint Interrupt: %s", (active)? "Asserted" : "Deasserted");
|
||||||
g_VideoInitialize.pSetInterrupt(INT_CAUSE_CP, true);
|
g_VideoInitialize.pSetInterrupt(INT_CAUSE_CP, active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void UpdateInterruptsFromVideoPlugin()
|
void UpdateInterruptsFromVideoPlugin()
|
||||||
{
|
{
|
||||||
g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, 0);
|
g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate)
|
||||||
|
{
|
||||||
|
UpdateInterrupts();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void SetFifoIdleFromVideoPlugin()
|
void SetFifoIdleFromVideoPlugin()
|
||||||
{
|
{
|
||||||
s_fifoIdleEvent.Set();
|
s_fifoIdleEvent.Set();
|
||||||
|
|
|
@ -148,8 +148,8 @@ void Write32(const u32 _Data, const u32 _Address);
|
||||||
void CatchUpGPU();
|
void CatchUpGPU();
|
||||||
void GatherPipeBursted();
|
void GatherPipeBursted();
|
||||||
void UpdateFifoRegister();
|
void UpdateFifoRegister();
|
||||||
void UpdateInterrupts();
|
void UpdateInterrupts(bool active);
|
||||||
void UpdateInterruptsFromVideoPlugin();
|
//void UpdateInterruptsFromVideoPlugin();
|
||||||
void SetFifoIdleFromVideoPlugin();
|
void SetFifoIdleFromVideoPlugin();
|
||||||
|
|
||||||
bool AllowIdleSkipping();
|
bool AllowIdleSkipping();
|
||||||
|
|
|
@ -35,7 +35,6 @@ typedef struct
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
TLog pLog;
|
TLog pLog;
|
||||||
int padNumber;
|
|
||||||
} SPADInitialize;
|
} SPADInitialize;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
|
@ -714,7 +714,6 @@ void Shutdown()
|
||||||
g_EmulatorRunning = false;
|
g_EmulatorRunning = false;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
dinput.Free();
|
|
||||||
// Kill xpad rumble
|
// Kill xpad rumble
|
||||||
XINPUT_VIBRATION vib;
|
XINPUT_VIBRATION vib;
|
||||||
vib.wLeftMotorSpeed = 0;
|
vib.wLeftMotorSpeed = 0;
|
||||||
|
@ -722,6 +721,7 @@ void Shutdown()
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
if (pad[i].bRumble)
|
if (pad[i].bRumble)
|
||||||
XInputSetState(pad[i].XPadPlayer, &vib);
|
XInputSetState(pad[i].XPadPlayer, &vib);
|
||||||
|
dinput.Free();
|
||||||
#endif
|
#endif
|
||||||
SaveConfig();
|
SaveConfig();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue