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
|
||||
{
|
||||
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 )
|
||||
{
|
||||
|
@ -275,11 +275,11 @@ namespace Threading
|
|||
else
|
||||
{
|
||||
// In order to avoid deadlock we need to make sure we cut some time
|
||||
// to handle messages. I choose 200ms:
|
||||
// to handle messages.
|
||||
|
||||
do {
|
||||
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) );
|
||||
|
||||
// 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 {
|
||||
wxTheApp->ProcessPendingEvents();
|
||||
if( (sem_timedwait( &sema, &ts_msec_200 ) == -1) && (errno == ETIMEDOUT) )
|
||||
break;
|
||||
countdown -= pass;
|
||||
if( Wait( ts_msec_250 ) ) break;
|
||||
countdown -= ts_msec_250;
|
||||
} while( countdown.GetMilliseconds() > 0 );
|
||||
|
||||
return countdown.GetMilliseconds() > 0;
|
||||
|
@ -316,7 +314,8 @@ namespace Threading
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,31 +70,22 @@ static int mg_BIToffset(u8 *buffer)
|
|||
return ofs + 0x20;
|
||||
}
|
||||
|
||||
FILE *_cdvdOpenMechaVer() {
|
||||
char *ptr;
|
||||
int i;
|
||||
char file[g_MaxPath];
|
||||
FILE *_cdvdOpenMechaVer()
|
||||
{
|
||||
FILE* fd;
|
||||
|
||||
// get the name of the bios file
|
||||
|
||||
// use the bios filename to get the name of the mecha ver file
|
||||
// [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, "MEC");
|
||||
wxFileName mecfile(EmuConfig.BiosFilename);
|
||||
mecfile.SetExt( L"mec" );
|
||||
wxCharBuffer file( mecfile.GetFullPath().ToUTF8() );
|
||||
|
||||
// if file doesnt exist, create empty one
|
||||
fd = fopen(file, "r+b");
|
||||
if (fd == NULL) {
|
||||
fd = fopen(file.data(), "r+b");
|
||||
if (fd == NULL)
|
||||
{
|
||||
Console::Notice("MEC File Not Found , Creating Blank File");
|
||||
fd = fopen(file, "wb");
|
||||
fd = fopen(file.data(), "wb");
|
||||
if (fd == NULL)
|
||||
{
|
||||
Console::Error( "\tMEC File Creation failed!" );
|
||||
|
@ -121,38 +112,26 @@ s32 cdvdGetMechaVer(u8* ver)
|
|||
return 0;
|
||||
}
|
||||
|
||||
FILE *_cdvdOpenNVM() {
|
||||
char *ptr;
|
||||
int i;
|
||||
char file[g_MaxPath];
|
||||
FILE *_cdvdOpenNVM()
|
||||
{
|
||||
FILE* fd;
|
||||
|
||||
// get the name of the bios file
|
||||
|
||||
// use the bios filename to get the name of the nvm file
|
||||
// [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");
|
||||
wxFileName nvmfile(EmuConfig.BiosFilename);
|
||||
nvmfile.SetExt( L"nvm" );
|
||||
wxCharBuffer file( nvmfile.GetFullPath().ToUTF8() );
|
||||
|
||||
// if file doesnt exist, create empty one
|
||||
fd = fopen(file, "r+b");
|
||||
if (fd == NULL) {
|
||||
fd = fopen(file.data(), "r+b");
|
||||
if (fd == NULL)
|
||||
{
|
||||
Console::Notice("NVM File Not Found , Creating Blank File");
|
||||
fd = fopen(file, "wb");
|
||||
fd = fopen(file.data(), "wb");
|
||||
if (fd == NULL)
|
||||
{
|
||||
Console::Error( "\tMEC File Creation failed!" );
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -173,6 +173,25 @@ public:
|
|||
|
||||
VideoOptions();
|
||||
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;
|
||||
ProfilerOptions Profiler;
|
||||
|
||||
wxFileName BiosFilename;
|
||||
|
||||
Pcsx2Config();
|
||||
void LoadSave( IniInterface& ini );
|
||||
|
||||
|
@ -262,6 +283,23 @@ public:
|
|||
void Load( const wxInputStream& srcstream );
|
||||
void Save( const wxString& dstfile );
|
||||
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()
|
||||
{
|
||||
if( sysInitialized )
|
||||
SysShutdown();
|
||||
|
||||
vuMicroMemShutdown();
|
||||
psxMemShutdown();
|
||||
memShutdown();
|
||||
vtlb_Core_Shutdown();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
// 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.
|
||||
SuperVUDestroy( -1 );
|
||||
|
||||
VU0micro::recShutdown();
|
||||
VU1micro::recShutdown();
|
||||
|
||||
psxRec.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.
|
||||
// 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
|
||||
|
@ -312,6 +326,7 @@ void SysExecute( CoreEmuThread* newThread )
|
|||
void SysEndExecution()
|
||||
{
|
||||
safe_delete( g_EmuThread );
|
||||
GetPluginManager().Shutdown();
|
||||
}
|
||||
|
||||
void SysSuspend()
|
||||
|
@ -359,12 +374,12 @@ void SysLoadState( const wxString& file )
|
|||
GSsetGameCRC(ElfCRC, g_ZeroGSOptions);
|
||||
}
|
||||
|
||||
void SysShutdown()
|
||||
void SysReset()
|
||||
{
|
||||
Console::Status( "Resetting..." );
|
||||
Console::Status( "Resetting PS2 virtual machine..." );
|
||||
|
||||
safe_delete( g_EmuThread );
|
||||
GetPluginManager().Shutdown();
|
||||
SysShutdown();
|
||||
StateRecovery::Clear();
|
||||
ElfCRC = 0;
|
||||
|
||||
// Note : No need to call cpuReset() here. It gets called automatically before the
|
||||
|
@ -413,8 +428,10 @@ bool SysInit()
|
|||
if( sysInitialized ) return true;
|
||||
sysInitialized = true;
|
||||
|
||||
PCSX2_MEM_PROTECT_BEGIN();
|
||||
SysDetect();
|
||||
|
||||
PCSX2_MEM_PROTECT_BEGIN();
|
||||
Console::Status( "Initializing PS2 virtual machine..." );
|
||||
if( !SysAllocateMem() )
|
||||
return false; // critical memory allocation failure;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class CoreEmuThread;
|
|||
|
||||
extern bool SysInit();
|
||||
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, 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 SysShutdownDynarecs();
|
||||
extern void SysShutdownMem();
|
||||
extern void SysShutdown();
|
||||
|
||||
extern void SysLoadState( const wxString& file );
|
||||
extern void SysRestorableReset(); // Saves the current emulation state prior to spu reset.
|
||||
|
|
|
@ -234,6 +234,8 @@ public:
|
|||
|
||||
bool OnInit();
|
||||
int OnExit();
|
||||
void CleanUp();
|
||||
|
||||
void OnInitCmdLine( wxCmdLineParser& parser );
|
||||
bool OnCmdLineParsed( wxCmdLineParser& parser );
|
||||
bool OnCmdLineError( wxCmdLineParser& parser );
|
||||
|
|
|
@ -457,6 +457,8 @@ void AppConfig::Apply()
|
|||
Folders.Savestates.Mkdir();
|
||||
Folders.Snapshots.Mkdir();
|
||||
|
||||
g_Conf->EmuOptions.BiosFilename = g_Conf->FullpathToBios();
|
||||
|
||||
// Update the compression attribute on the Memcards folder.
|
||||
// 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)
|
||||
{
|
||||
SysShutdown();
|
||||
SysReset();
|
||||
Close();
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ void MainEmuFrame::Menu_EmuPause_Click(wxCommandEvent &event)
|
|||
void MainEmuFrame::Menu_EmuReset_Click(wxCommandEvent &event)
|
||||
{
|
||||
bool wasRunning = EmulationInProgress();
|
||||
SysShutdown();
|
||||
SysReset();
|
||||
|
||||
GetMenuBar()->Check( MenuId_Emu_Pause, false );
|
||||
|
||||
|
|
|
@ -75,6 +75,8 @@ void AppEmuThread::Resume()
|
|||
m_kevt.m_controlDown = false;
|
||||
m_kevt.m_altDown = false;
|
||||
|
||||
ApplySettings( g_Conf->EmuOptions );
|
||||
|
||||
CoreEmuThread::Resume();
|
||||
}
|
||||
|
||||
|
@ -464,13 +466,22 @@ void Pcsx2App::OnMessageBox( pxMessageBoxEvent& evt )
|
|||
Msgbox::OnEvent( evt );
|
||||
}
|
||||
|
||||
#include <wx/intl.h>
|
||||
|
||||
void Pcsx2App::CleanupMess()
|
||||
{
|
||||
SysShutdown();
|
||||
safe_delete( m_Bitmap_Logo );
|
||||
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
|
||||
{
|
||||
try
|
||||
|
@ -531,6 +542,8 @@ Pcsx2App::Pcsx2App() :
|
|||
Pcsx2App::~Pcsx2App()
|
||||
{
|
||||
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.
|
||||
void CoreEmuThread::ApplySettings( const Pcsx2Config& src )
|
||||
{
|
||||
if( src == EmuConfig ) return;
|
||||
|
||||
const bool isRunning = IsRunning();
|
||||
Suspend();
|
||||
|
||||
|
|
Loading…
Reference in New Issue