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:
Jake.Stine 2009-09-09 14:08:15 +00:00
parent f02c04cb3b
commit 8eb8f1bcea
10 changed files with 116 additions and 63 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 );
}
};
//////////////////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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.

View File

@ -234,6 +234,8 @@ public:
bool OnInit();
int OnExit();
void CleanUp();
void OnInitCmdLine( wxCmdLineParser& parser );
bool OnCmdLineParsed( wxCmdLineParser& parser );
bool OnCmdLineError( wxCmdLineParser& parser );

View File

@ -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.

View File

@ -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 );

View File

@ -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();
}

View File

@ -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();