mirror of https://github.com/PCSX2/pcsx2.git
Emulation options (speedhacks, CPU, etc) should work now, and fixed a few memleaks on exit, and crash-on-close bugs caused by more mis-used pthreads timedwait parameters.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1800 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
f02c04cb3b
commit
8eb8f1bcea
|
@ -29,7 +29,7 @@ using namespace Threading;
|
||||||
|
|
||||||
namespace Threading
|
namespace Threading
|
||||||
{
|
{
|
||||||
static const timespec ts_msec_200 = { 0, 200 * 1000000 };
|
static const wxTimeSpan ts_msec_250( 0, 0, 0, 250 );
|
||||||
|
|
||||||
static void _pt_callback_cleanup( void* handle )
|
static void _pt_callback_cleanup( void* handle )
|
||||||
{
|
{
|
||||||
|
@ -275,11 +275,11 @@ namespace Threading
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// In order to avoid deadlock we need to make sure we cut some time
|
// In order to avoid deadlock we need to make sure we cut some time
|
||||||
// to handle messages. I choose 200ms:
|
// to handle messages.
|
||||||
|
|
||||||
do {
|
do {
|
||||||
wxTheApp->ProcessPendingEvents();
|
wxTheApp->ProcessPendingEvents();
|
||||||
} while( (sem_timedwait( &sema, &ts_msec_200 ) == -1) && (errno == ETIMEDOUT) );
|
} while( !Wait( ts_msec_250 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,14 +294,12 @@ namespace Threading
|
||||||
wxTimeSpan countdown( (timeout) );
|
wxTimeSpan countdown( (timeout) );
|
||||||
|
|
||||||
// In order to avoid deadlock we need to make sure we cut some time
|
// In order to avoid deadlock we need to make sure we cut some time
|
||||||
// to handle messages. I choose 200ms:
|
// to handle messages.
|
||||||
|
|
||||||
static const wxTimeSpan pass( 0, 0, 0, 200 );
|
|
||||||
do {
|
do {
|
||||||
wxTheApp->ProcessPendingEvents();
|
wxTheApp->ProcessPendingEvents();
|
||||||
if( (sem_timedwait( &sema, &ts_msec_200 ) == -1) && (errno == ETIMEDOUT) )
|
if( Wait( ts_msec_250 ) ) break;
|
||||||
break;
|
countdown -= ts_msec_250;
|
||||||
countdown -= pass;
|
|
||||||
} while( countdown.GetMilliseconds() > 0 );
|
} while( countdown.GetMilliseconds() > 0 );
|
||||||
|
|
||||||
return countdown.GetMilliseconds() > 0;
|
return countdown.GetMilliseconds() > 0;
|
||||||
|
@ -316,7 +314,8 @@ namespace Threading
|
||||||
|
|
||||||
bool Semaphore::Wait( const wxTimeSpan& timeout )
|
bool Semaphore::Wait( const wxTimeSpan& timeout )
|
||||||
{
|
{
|
||||||
const timespec fail = { timeout.GetSeconds().GetLo(), 0 };
|
wxDateTime megafail( wxDateTime::UNow() + timeout );
|
||||||
|
const timespec fail = { megafail.GetTicks(), megafail.GetMillisecond() * 1000000 };
|
||||||
return sem_timedwait( &sema, &fail ) != -1;
|
return sem_timedwait( &sema, &fail ) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,31 +70,22 @@ static int mg_BIToffset(u8 *buffer)
|
||||||
return ofs + 0x20;
|
return ofs + 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *_cdvdOpenMechaVer() {
|
FILE *_cdvdOpenMechaVer()
|
||||||
char *ptr;
|
{
|
||||||
int i;
|
|
||||||
char file[g_MaxPath];
|
|
||||||
FILE* fd;
|
FILE* fd;
|
||||||
|
|
||||||
// get the name of the bios file
|
// get the name of the bios file
|
||||||
|
|
||||||
// use the bios filename to get the name of the mecha ver file
|
wxFileName mecfile(EmuConfig.BiosFilename);
|
||||||
// [TODO] : Upgrade this to use wxstring!
|
mecfile.SetExt( L"mec" );
|
||||||
|
wxCharBuffer file( mecfile.GetFullPath().ToUTF8() );
|
||||||
strcpy(file, g_Conf->FullpathToBios().ToAscii().data() );
|
|
||||||
|
|
||||||
ptr = file;
|
|
||||||
i = (int)strlen(file);
|
|
||||||
|
|
||||||
while (i > 0) { if (ptr[i] == '.') break; i--; }
|
|
||||||
ptr[i+1] = '\0';
|
|
||||||
strcat(file, "MEC");
|
|
||||||
|
|
||||||
// if file doesnt exist, create empty one
|
// if file doesnt exist, create empty one
|
||||||
fd = fopen(file, "r+b");
|
fd = fopen(file.data(), "r+b");
|
||||||
if (fd == NULL) {
|
if (fd == NULL)
|
||||||
|
{
|
||||||
Console::Notice("MEC File Not Found , Creating Blank File");
|
Console::Notice("MEC File Not Found , Creating Blank File");
|
||||||
fd = fopen(file, "wb");
|
fd = fopen(file.data(), "wb");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
Console::Error( "\tMEC File Creation failed!" );
|
Console::Error( "\tMEC File Creation failed!" );
|
||||||
|
@ -121,38 +112,26 @@ s32 cdvdGetMechaVer(u8* ver)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *_cdvdOpenNVM() {
|
FILE *_cdvdOpenNVM()
|
||||||
char *ptr;
|
{
|
||||||
int i;
|
|
||||||
char file[g_MaxPath];
|
|
||||||
FILE* fd;
|
FILE* fd;
|
||||||
|
|
||||||
// get the name of the bios file
|
wxFileName nvmfile(EmuConfig.BiosFilename);
|
||||||
|
nvmfile.SetExt( L"nvm" );
|
||||||
// use the bios filename to get the name of the nvm file
|
wxCharBuffer file( nvmfile.GetFullPath().ToUTF8() );
|
||||||
// [TODO] : Upgrade this to use wxString!
|
|
||||||
|
|
||||||
strcpy( file, g_Conf->FullpathToBios().ToAscii().data() );
|
|
||||||
ptr = file;
|
|
||||||
i = (int)strlen(file);
|
|
||||||
|
|
||||||
while (i > 0) { if (ptr[i] == '.') break; i--; }
|
|
||||||
ptr[i+1] = '\0';
|
|
||||||
|
|
||||||
strcat(file, "NVM");
|
|
||||||
|
|
||||||
// if file doesnt exist, create empty one
|
// if file doesnt exist, create empty one
|
||||||
fd = fopen(file, "r+b");
|
fd = fopen(file.data(), "r+b");
|
||||||
if (fd == NULL) {
|
if (fd == NULL)
|
||||||
|
{
|
||||||
Console::Notice("NVM File Not Found , Creating Blank File");
|
Console::Notice("NVM File Not Found , Creating Blank File");
|
||||||
fd = fopen(file, "wb");
|
fd = fopen(file.data(), "wb");
|
||||||
if (fd == NULL)
|
if (fd == NULL)
|
||||||
{
|
{
|
||||||
|
Console::Error( "\tMEC File Creation failed!" );
|
||||||
throw Exception::CreateStream( file );
|
throw Exception::CreateStream( file );
|
||||||
//Msgbox::Alert("_cdvdOpenNVM: Error creating %s", file);
|
|
||||||
//exit(1);
|
|
||||||
}
|
}
|
||||||
for (i=0; i<1024; i++) fputc(0, fd);
|
for (int i=0; i<1024; i++) fputc(0, fd);
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,6 +173,25 @@ public:
|
||||||
|
|
||||||
VideoOptions();
|
VideoOptions();
|
||||||
void LoadSave( IniInterface& conf );
|
void LoadSave( IniInterface& conf );
|
||||||
|
|
||||||
|
bool operator ==( const VideoOptions& right ) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
OpEqu( EnableFrameSkipping ) &&
|
||||||
|
OpEqu( EnableFrameLimiting ) &&
|
||||||
|
OpEqu( DefaultRegionMode ) &&
|
||||||
|
OpEqu( FpsTurbo ) &&
|
||||||
|
OpEqu( FpsLimit ) &&
|
||||||
|
OpEqu( FpsSkip ) &&
|
||||||
|
OpEqu( ConsecutiveFrames ) &&
|
||||||
|
OpEqu( ConsecutiveSkip );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator !=( const VideoOptions& right ) const
|
||||||
|
{
|
||||||
|
return !this->operator ==( right );
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -255,6 +274,8 @@ public:
|
||||||
GamefixOptions Gamefixes;
|
GamefixOptions Gamefixes;
|
||||||
ProfilerOptions Profiler;
|
ProfilerOptions Profiler;
|
||||||
|
|
||||||
|
wxFileName BiosFilename;
|
||||||
|
|
||||||
Pcsx2Config();
|
Pcsx2Config();
|
||||||
void LoadSave( IniInterface& ini );
|
void LoadSave( IniInterface& ini );
|
||||||
|
|
||||||
|
@ -262,6 +283,23 @@ public:
|
||||||
void Load( const wxInputStream& srcstream );
|
void Load( const wxInputStream& srcstream );
|
||||||
void Save( const wxString& dstfile );
|
void Save( const wxString& dstfile );
|
||||||
void Save( const wxOutputStream& deststream );
|
void Save( const wxOutputStream& deststream );
|
||||||
|
|
||||||
|
bool operator ==( const Pcsx2Config& right ) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
OpEqu( bitset ) &&
|
||||||
|
OpEqu( Cpu ) &&
|
||||||
|
OpEqu( Video ) &&
|
||||||
|
OpEqu( Speedhacks ) &&
|
||||||
|
OpEqu( Gamefixes ) &&
|
||||||
|
OpEqu( Profiler ) &&
|
||||||
|
OpEqu( BiosFilename );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator !=( const Pcsx2Config& right ) const
|
||||||
|
{
|
||||||
|
return !this->operator ==( right );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -235,18 +235,19 @@ void SysAllocateDynarecs()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
// This should be called last thing before PCSX2 exits.
|
||||||
// This should be called last thing before Pcsx2 exits.
|
|
||||||
//
|
//
|
||||||
void SysShutdownMem()
|
void SysShutdownMem()
|
||||||
{
|
{
|
||||||
|
if( sysInitialized )
|
||||||
|
SysShutdown();
|
||||||
|
|
||||||
vuMicroMemShutdown();
|
vuMicroMemShutdown();
|
||||||
psxMemShutdown();
|
psxMemShutdown();
|
||||||
memShutdown();
|
memShutdown();
|
||||||
vtlb_Core_Shutdown();
|
vtlb_Core_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// This should generally be called right before calling SysShutdownMem(), although you can optionally
|
// This should generally be called right before calling SysShutdownMem(), although you can optionally
|
||||||
// use it in conjunction with SysAllocDynarecs to allocate/free the dynarec resources on the fly (as
|
// use it in conjunction with SysAllocDynarecs to allocate/free the dynarec resources on the fly (as
|
||||||
// risky as it might be, since dynarecs could very well fail on the second attempt).
|
// risky as it might be, since dynarecs could very well fail on the second attempt).
|
||||||
|
@ -255,12 +256,25 @@ void SysShutdownDynarecs()
|
||||||
// Special SuperVU "complete" terminator.
|
// Special SuperVU "complete" terminator.
|
||||||
SuperVUDestroy( -1 );
|
SuperVUDestroy( -1 );
|
||||||
|
|
||||||
|
VU0micro::recShutdown();
|
||||||
|
VU1micro::recShutdown();
|
||||||
|
|
||||||
psxRec.Shutdown();
|
psxRec.Shutdown();
|
||||||
recCpu.Shutdown();
|
recCpu.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SysShutdown()
|
||||||
|
{
|
||||||
|
sysInitialized = false;
|
||||||
|
|
||||||
|
Console::Status( "Shutting down PS2 virtual machine..." );
|
||||||
|
SysEndExecution();
|
||||||
|
safe_delete( g_plugins );
|
||||||
|
|
||||||
|
SysShutdownDynarecs();
|
||||||
|
SysShutdownMem();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Resets all PS2 cpu execution caches, which does not affect that actual PS2 state/condition.
|
// Resets all PS2 cpu execution caches, which does not affect that actual PS2 state/condition.
|
||||||
// This can be called at any time outside the context of a Cpu->Execute() block without
|
// This can be called at any time outside the context of a Cpu->Execute() block without
|
||||||
// bad things happening (recompilers will slow down for a brief moment since rec code blocks
|
// bad things happening (recompilers will slow down for a brief moment since rec code blocks
|
||||||
|
@ -312,6 +326,7 @@ void SysExecute( CoreEmuThread* newThread )
|
||||||
void SysEndExecution()
|
void SysEndExecution()
|
||||||
{
|
{
|
||||||
safe_delete( g_EmuThread );
|
safe_delete( g_EmuThread );
|
||||||
|
GetPluginManager().Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysSuspend()
|
void SysSuspend()
|
||||||
|
@ -359,12 +374,12 @@ void SysLoadState( const wxString& file )
|
||||||
GSsetGameCRC(ElfCRC, g_ZeroGSOptions);
|
GSsetGameCRC(ElfCRC, g_ZeroGSOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SysShutdown()
|
void SysReset()
|
||||||
{
|
{
|
||||||
Console::Status( "Resetting..." );
|
Console::Status( "Resetting PS2 virtual machine..." );
|
||||||
|
|
||||||
safe_delete( g_EmuThread );
|
SysShutdown();
|
||||||
GetPluginManager().Shutdown();
|
StateRecovery::Clear();
|
||||||
ElfCRC = 0;
|
ElfCRC = 0;
|
||||||
|
|
||||||
// Note : No need to call cpuReset() here. It gets called automatically before the
|
// Note : No need to call cpuReset() here. It gets called automatically before the
|
||||||
|
@ -413,8 +428,10 @@ bool SysInit()
|
||||||
if( sysInitialized ) return true;
|
if( sysInitialized ) return true;
|
||||||
sysInitialized = true;
|
sysInitialized = true;
|
||||||
|
|
||||||
PCSX2_MEM_PROTECT_BEGIN();
|
|
||||||
SysDetect();
|
SysDetect();
|
||||||
|
|
||||||
|
PCSX2_MEM_PROTECT_BEGIN();
|
||||||
|
Console::Status( "Initializing PS2 virtual machine..." );
|
||||||
if( !SysAllocateMem() )
|
if( !SysAllocateMem() )
|
||||||
return false; // critical memory allocation failure;
|
return false; // critical memory allocation failure;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ class CoreEmuThread;
|
||||||
|
|
||||||
extern bool SysInit();
|
extern bool SysInit();
|
||||||
extern void SysDetect(); // Detects cpu type and fills cpuInfo structs.
|
extern void SysDetect(); // Detects cpu type and fills cpuInfo structs.
|
||||||
extern void SysShutdown(); // Resets the various PS2 cpus, sub-systems, and recompilers.
|
extern void SysReset(); // Resets the various PS2 cpus, sub-systems, and recompilers.
|
||||||
|
|
||||||
extern void SysExecute( CoreEmuThread* newThread );
|
extern void SysExecute( CoreEmuThread* newThread );
|
||||||
extern void SysExecute( CoreEmuThread* newThread, CDVD_SourceType cdvdsrc );
|
extern void SysExecute( CoreEmuThread* newThread, CDVD_SourceType cdvdsrc );
|
||||||
|
@ -43,6 +43,7 @@ extern bool SysAllocateMem(); // allocates memory for all PS2 systems; returns
|
||||||
extern void SysAllocateDynarecs(); // allocates memory for all dynarecs, and force-disables any failures.
|
extern void SysAllocateDynarecs(); // allocates memory for all dynarecs, and force-disables any failures.
|
||||||
extern void SysShutdownDynarecs();
|
extern void SysShutdownDynarecs();
|
||||||
extern void SysShutdownMem();
|
extern void SysShutdownMem();
|
||||||
|
extern void SysShutdown();
|
||||||
|
|
||||||
extern void SysLoadState( const wxString& file );
|
extern void SysLoadState( const wxString& file );
|
||||||
extern void SysRestorableReset(); // Saves the current emulation state prior to spu reset.
|
extern void SysRestorableReset(); // Saves the current emulation state prior to spu reset.
|
||||||
|
|
|
@ -234,6 +234,8 @@ public:
|
||||||
|
|
||||||
bool OnInit();
|
bool OnInit();
|
||||||
int OnExit();
|
int OnExit();
|
||||||
|
void CleanUp();
|
||||||
|
|
||||||
void OnInitCmdLine( wxCmdLineParser& parser );
|
void OnInitCmdLine( wxCmdLineParser& parser );
|
||||||
bool OnCmdLineParsed( wxCmdLineParser& parser );
|
bool OnCmdLineParsed( wxCmdLineParser& parser );
|
||||||
bool OnCmdLineError( wxCmdLineParser& parser );
|
bool OnCmdLineError( wxCmdLineParser& parser );
|
||||||
|
|
|
@ -457,6 +457,8 @@ void AppConfig::Apply()
|
||||||
Folders.Savestates.Mkdir();
|
Folders.Savestates.Mkdir();
|
||||||
Folders.Snapshots.Mkdir();
|
Folders.Snapshots.Mkdir();
|
||||||
|
|
||||||
|
g_Conf->EmuOptions.BiosFilename = g_Conf->FullpathToBios();
|
||||||
|
|
||||||
// Update the compression attribute on the Memcards folder.
|
// Update the compression attribute on the Memcards folder.
|
||||||
// Memcards generally compress very well via NTFS compression.
|
// Memcards generally compress very well via NTFS compression.
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ void MainEmuFrame::Menu_SaveStateOther_Click(wxCommandEvent &event)
|
||||||
|
|
||||||
void MainEmuFrame::Menu_Exit_Click(wxCommandEvent &event)
|
void MainEmuFrame::Menu_Exit_Click(wxCommandEvent &event)
|
||||||
{
|
{
|
||||||
SysShutdown();
|
SysReset();
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ void MainEmuFrame::Menu_EmuPause_Click(wxCommandEvent &event)
|
||||||
void MainEmuFrame::Menu_EmuReset_Click(wxCommandEvent &event)
|
void MainEmuFrame::Menu_EmuReset_Click(wxCommandEvent &event)
|
||||||
{
|
{
|
||||||
bool wasRunning = EmulationInProgress();
|
bool wasRunning = EmulationInProgress();
|
||||||
SysShutdown();
|
SysReset();
|
||||||
|
|
||||||
GetMenuBar()->Check( MenuId_Emu_Pause, false );
|
GetMenuBar()->Check( MenuId_Emu_Pause, false );
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,8 @@ void AppEmuThread::Resume()
|
||||||
m_kevt.m_controlDown = false;
|
m_kevt.m_controlDown = false;
|
||||||
m_kevt.m_altDown = false;
|
m_kevt.m_altDown = false;
|
||||||
|
|
||||||
|
ApplySettings( g_Conf->EmuOptions );
|
||||||
|
|
||||||
CoreEmuThread::Resume();
|
CoreEmuThread::Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,13 +466,22 @@ void Pcsx2App::OnMessageBox( pxMessageBoxEvent& evt )
|
||||||
Msgbox::OnEvent( evt );
|
Msgbox::OnEvent( evt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <wx/intl.h>
|
||||||
|
|
||||||
void Pcsx2App::CleanupMess()
|
void Pcsx2App::CleanupMess()
|
||||||
{
|
{
|
||||||
SysShutdown();
|
|
||||||
safe_delete( m_Bitmap_Logo );
|
safe_delete( m_Bitmap_Logo );
|
||||||
safe_delete( g_Conf );
|
safe_delete( g_Conf );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This cleanup procedure is issued by wxWidgets prior to destroying base windows and window
|
||||||
|
// classes.
|
||||||
|
void Pcsx2App::CleanUp()
|
||||||
|
{
|
||||||
|
SysShutdown();
|
||||||
|
wxApp::CleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
void Pcsx2App::HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const
|
void Pcsx2App::HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -531,6 +542,8 @@ Pcsx2App::Pcsx2App() :
|
||||||
Pcsx2App::~Pcsx2App()
|
Pcsx2App::~Pcsx2App()
|
||||||
{
|
{
|
||||||
CleanupMess();
|
CleanupMess();
|
||||||
|
while( wxGetLocale() != NULL )
|
||||||
|
delete wxGetLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -263,6 +263,8 @@ void CoreEmuThread::Suspend( bool isBlocking )
|
||||||
// is determined by comparing the current settings against the new settings.
|
// is determined by comparing the current settings against the new settings.
|
||||||
void CoreEmuThread::ApplySettings( const Pcsx2Config& src )
|
void CoreEmuThread::ApplySettings( const Pcsx2Config& src )
|
||||||
{
|
{
|
||||||
|
if( src == EmuConfig ) return;
|
||||||
|
|
||||||
const bool isRunning = IsRunning();
|
const bool isRunning = IsRunning();
|
||||||
Suspend();
|
Suspend();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue