mirror of https://github.com/PCSX2/pcsx2.git
wxgui: Connected up the CPU panel controls so that they do something, and fancied up the "Apply" button so that it ungrays only after changes to the config have been made. :)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1695 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
ab08bc730e
commit
e6f8b4e8d0
|
@ -387,7 +387,7 @@ void CALLBACK ISOnewDiskCB(void(CALLBACK*)())
|
|||
{
|
||||
}
|
||||
|
||||
wxString ISOgetUniqueFilename(__unused void (*callback)())
|
||||
wxString ISOgetUniqueFilename()
|
||||
{
|
||||
return Path::GetFilenameWithoutExt(wxString::FromAscii(isoFileName));
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ extern struct KeyModifiers keymodifiers;
|
|||
// So a rename to pDisplay is in the works, but it will not, in fact, be removed.
|
||||
extern uptr pDsp; //Used in GS, MTGS, Plugins, Misc
|
||||
|
||||
int GetPS2ElfName( wxString& dest ); // Used in Misc, System, Linux, CDVD
|
||||
extern int GetPS2ElfName( wxString& dest ); // Used in Misc, System, Linux, CDVD
|
||||
|
||||
// Not sure what header these should go in. Probably not this one.
|
||||
void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR);
|
||||
|
|
|
@ -408,6 +408,7 @@ CDVD_API CDVDapi_Plugin =
|
|||
// The rest are filled in by the plugin manager
|
||||
NULL
|
||||
};
|
||||
|
||||
CDVD_API* CDVD = NULL;
|
||||
|
||||
static const LegacyApi_ReqMethod s_MethMessReq_CDVD[] =
|
||||
|
|
|
@ -122,8 +122,10 @@ public:
|
|||
bool OnCmdLineParsed( wxCmdLineParser& parser );
|
||||
|
||||
bool PrepForExit();
|
||||
|
||||
//void OnAssertionFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg );
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
void OnAssertFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg );
|
||||
#endif
|
||||
|
||||
const wxBitmap& GetLogoBitmap();
|
||||
wxImageList& GetImgList_Config();
|
||||
|
|
|
@ -453,7 +453,7 @@ void ConsoleLogFrame::OnClear(wxMenuEvent& WXUNUSED(event))
|
|||
m_TextCtrl.Clear();
|
||||
}
|
||||
|
||||
void ConsoleLogFrame::OnFontSize(wxMenuEvent& evt )
|
||||
void ConsoleLogFrame::OnFontSize( wxMenuEvent& evt )
|
||||
{
|
||||
int ptsize = 8;
|
||||
switch( evt.GetId() )
|
||||
|
|
|
@ -77,6 +77,8 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
|
|||
|
||||
mainSizer.Add( &m_listbook );
|
||||
AddOkCancel( mainSizer, true );
|
||||
|
||||
GetWindowChild( wxID_APPLY )->Disable();
|
||||
|
||||
SetSizerAndFit( &mainSizer );
|
||||
CenterOnScreen();
|
||||
|
@ -93,6 +95,23 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
|
|||
|
||||
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
|
||||
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Bind a variety of standard "something probably changed" events. If the user invokes
|
||||
// any of these, we'll automatically de-gray the Apply button for this dialog box. :)
|
||||
|
||||
#define ConnectSomethingChanged( command ) \
|
||||
Connect( wxEVT_COMMAND_##command, wxCommandEventHandler( ConfigurationDialog::OnSomethingChanged ) );
|
||||
|
||||
ConnectSomethingChanged( RADIOBUTTON_SELECTED );
|
||||
ConnectSomethingChanged( COMBOBOX_SELECTED );
|
||||
ConnectSomethingChanged( CHECKBOX_CLICKED );
|
||||
ConnectSomethingChanged( BUTTON_CLICKED );
|
||||
ConnectSomethingChanged( CHOICE_SELECTED );
|
||||
ConnectSomethingChanged( LISTBOX_SELECTED );
|
||||
ConnectSomethingChanged( SPINCTRL_UPDATED );
|
||||
ConnectSomethingChanged( SLIDER_UPDATED );
|
||||
ConnectSomethingChanged( DIRPICKER_CHANGED );
|
||||
}
|
||||
|
||||
Dialogs::ConfigurationDialog::~ConfigurationDialog()
|
||||
|
@ -111,7 +130,7 @@ void Dialogs::ConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
|
|||
|
||||
void Dialogs::ConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
|
||||
{
|
||||
evt.Skip();
|
||||
GetWindowChild( wxID_APPLY )->Disable();
|
||||
g_ApplyState.ApplyAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,15 @@ namespace Dialogs
|
|||
protected:
|
||||
void OnOk_Click( wxCommandEvent& evt );
|
||||
void OnApply_Click( wxCommandEvent& evt );
|
||||
|
||||
virtual void OnSomethingChanged( wxCommandEvent& evt )
|
||||
{
|
||||
evt.Skip();
|
||||
if( (evt.GetId() != wxID_OK) && (evt.GetId() != wxID_CANCEL) && (evt.GetId() != wxID_APPLY) )
|
||||
{
|
||||
GetWindowChild( wxID_APPLY )->Enable();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -209,6 +209,13 @@ namespace Panels
|
|||
class CpuPanel : public BaseApplicableConfigPanel
|
||||
{
|
||||
protected:
|
||||
wxRadioButton* m_Option_RecEE;
|
||||
wxRadioButton* m_Option_RecIOP;
|
||||
wxRadioButton* m_Option_mVU0;
|
||||
wxRadioButton* m_Option_mVU1;
|
||||
|
||||
wxRadioButton* m_Option_sVU0;
|
||||
wxRadioButton* m_Option_sVU1;
|
||||
|
||||
public:
|
||||
CpuPanel( wxWindow& parent, int idealWidth );
|
||||
|
|
|
@ -37,30 +37,58 @@ Panels::CpuPanel::CpuPanel( wxWindow& parent, int idealWidth ) :
|
|||
|
||||
m_StartNewRadioGroup = true;
|
||||
AddRadioButton( s_ee, _("Interpreter"), wxEmptyString, _("Quite possibly the slowest thing in the universe.") );
|
||||
AddRadioButton( s_ee, _("Recompiler") );
|
||||
m_Option_RecEE = &AddRadioButton( s_ee, _("Recompiler") );
|
||||
|
||||
m_StartNewRadioGroup = true;
|
||||
AddRadioButton( s_iop, _("Interpreter") );
|
||||
AddRadioButton( s_iop, _("Recompiler") );
|
||||
m_Option_RecIOP = &AddRadioButton( s_iop, _("Recompiler") );
|
||||
|
||||
m_StartNewRadioGroup = true;
|
||||
AddRadioButton( s_vu0, _("Interpreter") );
|
||||
AddRadioButton( s_vu0, _("microVU Recompiler [new!]") );
|
||||
AddRadioButton( s_vu0, _("superVU Recompiler [legacy]"), wxEmptyString, _("Useful for diagnosing possible bugs in the new mVU recompiler.") );
|
||||
AddRadioButton( s_vu0, _("Interpreter") ).SetValue( true );
|
||||
m_Option_mVU0 = &AddRadioButton( s_vu0, _("microVU Recompiler [new!]") );
|
||||
m_Option_sVU0 = &AddRadioButton( s_vu0, _("superVU Recompiler [legacy]"), wxEmptyString, _("Useful for diagnosing possible bugs in the new mVU recompiler.") );
|
||||
|
||||
m_StartNewRadioGroup = true;
|
||||
AddRadioButton( s_vu1, _("Interpreter") );
|
||||
AddRadioButton( s_vu1, _("microVU Recompiler [new!]") );
|
||||
AddRadioButton( s_vu1, _("superVU Recompiler [legacy]"), wxEmptyString, _("Useful for diagnosing possible bugs in the new mVU recompiler.") );
|
||||
AddRadioButton( s_vu1, _("Interpreter") ).SetValue( true );
|
||||
m_Option_mVU1 = &AddRadioButton( s_vu1, _("microVU Recompiler [new!]") );
|
||||
m_Option_sVU1 = &AddRadioButton( s_vu1, _("superVU Recompiler [legacy]"), wxEmptyString, _("Useful for diagnosing possible bugs in the new mVU recompiler.") );
|
||||
|
||||
s_main.Add( &s_ee, SizerFlags::StdExpand() );
|
||||
s_main.Add( &s_iop, SizerFlags::StdExpand() );
|
||||
s_main.Add( &s_vu0, SizerFlags::StdExpand() );
|
||||
s_main.Add( &s_vu1, SizerFlags::StdExpand() );
|
||||
|
||||
// [TODO] : Add advanced CPU settings -- FPU/VU rounding, clamping, etc.
|
||||
|
||||
SetSizer( &s_main );
|
||||
|
||||
SetSizerAndFit( &s_main );
|
||||
// ----------------------------------------------------------------------------
|
||||
// Apply current configuration options...
|
||||
|
||||
Pcsx2Config::RecompilerOptions& recOps( g_Conf->EmuOptions.Cpu.Recompiler );
|
||||
|
||||
m_Option_RecEE->SetValue( recOps.EnableEE );
|
||||
m_Option_RecIOP->SetValue( recOps.EnableIOP );
|
||||
|
||||
if( recOps.UseMicroVU0 )
|
||||
m_Option_mVU0->SetValue( recOps.EnableVU0 );
|
||||
else
|
||||
m_Option_sVU0->SetValue( recOps.EnableVU0 );
|
||||
|
||||
if( recOps.UseMicroVU1 )
|
||||
m_Option_mVU1->SetValue( recOps.EnableVU1 );
|
||||
else
|
||||
m_Option_sVU1->SetValue( recOps.EnableVU1 );
|
||||
}
|
||||
|
||||
void Panels::CpuPanel::Apply( AppConfig& conf )
|
||||
{
|
||||
Pcsx2Config::RecompilerOptions& recOps( conf.EmuOptions.Cpu.Recompiler );
|
||||
recOps.EnableEE = m_Option_RecEE->GetValue();
|
||||
recOps.EnableIOP = m_Option_RecIOP->GetValue();
|
||||
recOps.EnableVU0 = m_Option_mVU0->GetValue() || m_Option_sVU0->GetValue();
|
||||
recOps.EnableVU1 = m_Option_mVU1->GetValue() || m_Option_sVU1->GetValue();
|
||||
|
||||
recOps.UseMicroVU0 = m_Option_mVU0->GetValue();
|
||||
recOps.UseMicroVU1 = m_Option_mVU1->GetValue();
|
||||
}
|
||||
|
|
|
@ -48,13 +48,14 @@ void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
|
|||
}
|
||||
}
|
||||
|
||||
void Panels::DirPickerPanel::UseDefaultPath_Click( wxCommandEvent &event )
|
||||
void Panels::DirPickerPanel::UseDefaultPath_Click( wxCommandEvent &evt )
|
||||
{
|
||||
evt.Skip();
|
||||
wxASSERT( m_pickerCtrl != NULL && m_checkCtrl != NULL );
|
||||
UpdateCheckStatus( m_checkCtrl->IsChecked() );
|
||||
}
|
||||
|
||||
void Panels::DirPickerPanel::Explore_Click( wxCommandEvent &event )
|
||||
void Panels::DirPickerPanel::Explore_Click( wxCommandEvent &evt )
|
||||
{
|
||||
wxHelpers::Explore( m_pickerCtrl->GetPath() );
|
||||
}
|
||||
|
|
|
@ -241,6 +241,9 @@ Panels::PluginSelectorPanel::~PluginSelectorPanel()
|
|||
|
||||
void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
|
||||
{
|
||||
// user never entered plugins panel? Skip application since combo boxes are invalid/uninitialized.
|
||||
if( m_FileList == NULL ) return;
|
||||
|
||||
for( int i=0; i<NumPluginTypes; ++i )
|
||||
{
|
||||
int sel = m_ComponentBoxes.Get(i).GetSelection();
|
||||
|
|
|
@ -1,234 +1,234 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Common.h"
|
||||
#include "System.h"
|
||||
#include "SaveState.h"
|
||||
#include "Elfheader.h"
|
||||
#include "Plugins.h"
|
||||
#include "CoreEmuThread.h"
|
||||
|
||||
#include "R5900.h"
|
||||
#include "R3000A.h"
|
||||
#include "VUmicro.h"
|
||||
|
||||
static __threadlocal CoreEmuThread* tls_coreThread = NULL;
|
||||
|
||||
CoreEmuThread& CoreEmuThread::Get()
|
||||
{
|
||||
wxASSERT_MSG( tls_coreThread != NULL, L"This function must be called from the context of a running CoreEmuThread." );
|
||||
return *tls_coreThread;
|
||||
}
|
||||
|
||||
void CoreEmuThread::CpuInitializeMess()
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenPlugins();
|
||||
cpuReset();
|
||||
SysClearExecutionCache();
|
||||
|
||||
GSsetGameCRC( ElfCRC, 0 );
|
||||
|
||||
if( StateRecovery::HasState() )
|
||||
{
|
||||
// no need to boot bios or detect CDs when loading savestates.
|
||||
// [TODO] : It might be useful to detect game SLUS/CRC and compare it against
|
||||
// the savestate info, and issue a warning to the user since, chances are, they
|
||||
// don't really want to run a game with the wrong ISO loaded into the emu.
|
||||
StateRecovery::Recover();
|
||||
}
|
||||
else
|
||||
{
|
||||
ScopedLock lock( m_lock_elf_file );
|
||||
if( !m_elf_file.IsEmpty() )
|
||||
{
|
||||
// Skip Bios Hack -- Runs the PS2 BIOS stub, and then manually loads the ELF
|
||||
// executable data, and injects the cpuRegs.pc with the address of the
|
||||
// execution start point.
|
||||
//
|
||||
// This hack is necessary for non-CD ELF files, and is optional for game CDs
|
||||
// (though not recommended for games because of rare ill side effects).
|
||||
|
||||
cpuExecuteBios();
|
||||
loadElfFile( m_elf_file );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception::BaseException& ex )
|
||||
{
|
||||
Msgbox::Alert( ex.DisplayMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
sptr CoreEmuThread::ExecuteTask()
|
||||
{
|
||||
tls_coreThread = this;
|
||||
|
||||
while( !m_Done && (m_ExecMode != ExecMode_Running) )
|
||||
{
|
||||
m_ResumeEvent.Wait();
|
||||
}
|
||||
|
||||
CpuInitializeMess();
|
||||
|
||||
StateCheck();
|
||||
|
||||
PCSX2_MEM_PROTECT_BEGIN();
|
||||
Cpu->Execute();
|
||||
PCSX2_MEM_PROTECT_END();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CoreEmuThread::StateCheck()
|
||||
{
|
||||
{
|
||||
ScopedLock locker( m_lock_ExecMode );
|
||||
|
||||
switch( m_ExecMode )
|
||||
{
|
||||
case ExecMode_Idle:
|
||||
// threads should never have an idle execution state set while the
|
||||
// thread is in any way active or alive.
|
||||
DevAssert( false, "Invalid execution state detected." );
|
||||
break;
|
||||
|
||||
// These are not the case statements you're looking for. Move along.
|
||||
case ExecMode_Running: break;
|
||||
case ExecMode_Suspended: break;
|
||||
|
||||
case ExecMode_Suspending:
|
||||
m_ExecMode = ExecMode_Suspended;
|
||||
m_SuspendEvent.Post();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while( (m_ExecMode == ExecMode_Suspended) && !m_Done )
|
||||
{
|
||||
m_ResumeEvent.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
void CoreEmuThread::Start()
|
||||
{
|
||||
if( IsRunning() ) return;
|
||||
|
||||
m_running = false;
|
||||
m_ExecMode = ExecMode_Idle;
|
||||
m_Done = false;
|
||||
m_resetProfilers = false;
|
||||
m_resetRecompilers = false;
|
||||
m_elf_file = wxEmptyString;
|
||||
|
||||
m_ResumeEvent.Reset();
|
||||
m_SuspendEvent.Reset();
|
||||
PersistentThread::Start();
|
||||
|
||||
pthread_detach( m_thread );
|
||||
}
|
||||
|
||||
void CoreEmuThread::Reset()
|
||||
{
|
||||
Cancel();
|
||||
StateRecovery::Clear();
|
||||
}
|
||||
|
||||
// Resumes the core execution state, or does nothing is the core is already running. If
|
||||
// settings were changed, resets will be performed as needed and emulation state resumed from
|
||||
// memory savestates.
|
||||
void CoreEmuThread::Resume()
|
||||
{
|
||||
Start();
|
||||
|
||||
{
|
||||
ScopedLock locker( m_lock_ExecMode );
|
||||
|
||||
if( m_ExecMode == ExecMode_Running )
|
||||
return;
|
||||
|
||||
if( m_ExecMode == ExecMode_Suspending )
|
||||
{
|
||||
// if there are resets to be done, then we need to make sure and wait for the
|
||||
// emuThread to enter a fully suspended state before continuing...
|
||||
|
||||
if( m_resetRecompilers || m_resetProfilers )
|
||||
{
|
||||
locker.Unlock(); // no deadlocks please, thanks. :)
|
||||
m_SuspendEvent.Wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ExecMode = ExecMode_Running;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DevAssert( (m_ExecMode == ExecMode_Suspended) || (m_ExecMode == ExecMode_Idle),
|
||||
"EmuCoreThread is not in a suspended or idle state? wtf!" );
|
||||
}
|
||||
|
||||
if( m_resetRecompilers || m_resetProfilers )
|
||||
{
|
||||
SysClearExecutionCache();
|
||||
m_resetRecompilers = false;
|
||||
m_resetProfilers = false;
|
||||
}
|
||||
|
||||
m_ExecMode = ExecMode_Running;
|
||||
m_ResumeEvent.Post();
|
||||
}
|
||||
|
||||
// Pauses the emulation state at the next PS2 vsync, and returns control to the calling
|
||||
// thread; or does nothing if the core is already suspended. Calling this thread from the
|
||||
// Core thread will result in deadlock.
|
||||
//
|
||||
// Parameters:
|
||||
// isNonblocking - if set to true then the function will not block for emulation suspension.
|
||||
// Defaults to false if parameter is not specified. Performing non-blocking suspension
|
||||
// is mostly useful for starting certain non-Emu related gui activities (improves gui
|
||||
// responsiveness).
|
||||
//
|
||||
void CoreEmuThread::Suspend( bool isBlocking )
|
||||
{
|
||||
{
|
||||
ScopedLock locker( m_lock_ExecMode );
|
||||
|
||||
if( (m_ExecMode == ExecMode_Suspended) || (m_ExecMode == ExecMode_Idle) )
|
||||
return;
|
||||
|
||||
if( m_ExecMode == ExecMode_Running )
|
||||
m_ExecMode = ExecMode_Suspending;
|
||||
|
||||
DevAssert( m_ExecMode == ExecMode_Suspending, "ExecMode should be nothing other than Suspended..." );
|
||||
}
|
||||
|
||||
m_SuspendEvent.Wait();
|
||||
}
|
||||
|
||||
// Applies a full suite of new settings, which will automatically facilitate the necessary
|
||||
// resets of the core and components (including plugins, if needed). The scope of resetting
|
||||
// is determined by comparing the current settings against the new settings.
|
||||
void CoreEmuThread::ApplySettings( const Pcsx2Config& src )
|
||||
{
|
||||
m_resetRecompilers = ( src.Cpu != EmuConfig.Cpu ) || ( src.Gamefixes != EmuConfig.Gamefixes ) || ( src.Speedhacks != EmuConfig.Speedhacks );
|
||||
m_resetProfilers = (src.Profiler != EmuConfig.Profiler );
|
||||
EmuConfig = src;
|
||||
}
|
||||
#include "Common.h"
|
||||
#include "System.h"
|
||||
#include "SaveState.h"
|
||||
#include "Elfheader.h"
|
||||
#include "Plugins.h"
|
||||
#include "CoreEmuThread.h"
|
||||
|
||||
#include "R5900.h"
|
||||
#include "R3000A.h"
|
||||
#include "VUmicro.h"
|
||||
|
||||
static __threadlocal CoreEmuThread* tls_coreThread = NULL;
|
||||
|
||||
CoreEmuThread& CoreEmuThread::Get()
|
||||
{
|
||||
wxASSERT_MSG( tls_coreThread != NULL, L"This function must be called from the context of a running CoreEmuThread." );
|
||||
return *tls_coreThread;
|
||||
}
|
||||
|
||||
void CoreEmuThread::CpuInitializeMess()
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenPlugins();
|
||||
cpuReset();
|
||||
SysClearExecutionCache();
|
||||
|
||||
GSsetGameCRC( ElfCRC, 0 );
|
||||
|
||||
if( StateRecovery::HasState() )
|
||||
{
|
||||
// no need to boot bios or detect CDs when loading savestates.
|
||||
// [TODO] : It might be useful to detect game SLUS/CRC and compare it against
|
||||
// the savestate info, and issue a warning to the user since, chances are, they
|
||||
// don't really want to run a game with the wrong ISO loaded into the emu.
|
||||
StateRecovery::Recover();
|
||||
}
|
||||
else
|
||||
{
|
||||
ScopedLock lock( m_lock_elf_file );
|
||||
if( !m_elf_file.IsEmpty() )
|
||||
{
|
||||
// Skip Bios Hack -- Runs the PS2 BIOS stub, and then manually loads the ELF
|
||||
// executable data, and injects the cpuRegs.pc with the address of the
|
||||
// execution start point.
|
||||
//
|
||||
// This hack is necessary for non-CD ELF files, and is optional for game CDs
|
||||
// (though not recommended for games because of rare ill side effects).
|
||||
|
||||
cpuExecuteBios();
|
||||
loadElfFile( m_elf_file );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( Exception::BaseException& ex )
|
||||
{
|
||||
Msgbox::Alert( ex.DisplayMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
sptr CoreEmuThread::ExecuteTask()
|
||||
{
|
||||
tls_coreThread = this;
|
||||
|
||||
while( !m_Done && (m_ExecMode != ExecMode_Running) )
|
||||
{
|
||||
m_ResumeEvent.Wait();
|
||||
}
|
||||
|
||||
CpuInitializeMess();
|
||||
|
||||
StateCheck();
|
||||
|
||||
PCSX2_MEM_PROTECT_BEGIN();
|
||||
Cpu->Execute();
|
||||
PCSX2_MEM_PROTECT_END();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CoreEmuThread::StateCheck()
|
||||
{
|
||||
{
|
||||
ScopedLock locker( m_lock_ExecMode );
|
||||
|
||||
switch( m_ExecMode )
|
||||
{
|
||||
case ExecMode_Idle:
|
||||
// threads should never have an idle execution state set while the
|
||||
// thread is in any way active or alive.
|
||||
DevAssert( false, "Invalid execution state detected." );
|
||||
break;
|
||||
|
||||
// These are not the case statements you're looking for. Move along.
|
||||
case ExecMode_Running: break;
|
||||
case ExecMode_Suspended: break;
|
||||
|
||||
case ExecMode_Suspending:
|
||||
m_ExecMode = ExecMode_Suspended;
|
||||
m_SuspendEvent.Post();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while( (m_ExecMode == ExecMode_Suspended) && !m_Done )
|
||||
{
|
||||
m_ResumeEvent.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
void CoreEmuThread::Start()
|
||||
{
|
||||
if( IsRunning() ) return;
|
||||
|
||||
m_running = false;
|
||||
m_ExecMode = ExecMode_Idle;
|
||||
m_Done = false;
|
||||
m_resetProfilers = false;
|
||||
m_resetRecompilers = false;
|
||||
m_elf_file = wxEmptyString;
|
||||
|
||||
m_ResumeEvent.Reset();
|
||||
m_SuspendEvent.Reset();
|
||||
PersistentThread::Start();
|
||||
|
||||
pthread_detach( m_thread );
|
||||
}
|
||||
|
||||
void CoreEmuThread::Reset()
|
||||
{
|
||||
Cancel();
|
||||
StateRecovery::Clear();
|
||||
}
|
||||
|
||||
// Resumes the core execution state, or does nothing is the core is already running. If
|
||||
// settings were changed, resets will be performed as needed and emulation state resumed from
|
||||
// memory savestates.
|
||||
void CoreEmuThread::Resume()
|
||||
{
|
||||
Start();
|
||||
|
||||
{
|
||||
ScopedLock locker( m_lock_ExecMode );
|
||||
|
||||
if( m_ExecMode == ExecMode_Running )
|
||||
return;
|
||||
|
||||
if( m_ExecMode == ExecMode_Suspending )
|
||||
{
|
||||
// if there are resets to be done, then we need to make sure and wait for the
|
||||
// emuThread to enter a fully suspended state before continuing...
|
||||
|
||||
if( m_resetRecompilers || m_resetProfilers )
|
||||
{
|
||||
locker.Unlock(); // no deadlocks please, thanks. :)
|
||||
m_SuspendEvent.Wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ExecMode = ExecMode_Running;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DevAssert( (m_ExecMode == ExecMode_Suspended) || (m_ExecMode == ExecMode_Idle),
|
||||
"EmuCoreThread is not in a suspended or idle state? wtf!" );
|
||||
}
|
||||
|
||||
if( m_resetRecompilers || m_resetProfilers )
|
||||
{
|
||||
SysClearExecutionCache();
|
||||
m_resetRecompilers = false;
|
||||
m_resetProfilers = false;
|
||||
}
|
||||
|
||||
m_ExecMode = ExecMode_Running;
|
||||
m_ResumeEvent.Post();
|
||||
}
|
||||
|
||||
// Pauses the emulation state at the next PS2 vsync, and returns control to the calling
|
||||
// thread; or does nothing if the core is already suspended. Calling this thread from the
|
||||
// Core thread will result in deadlock.
|
||||
//
|
||||
// Parameters:
|
||||
// isNonblocking - if set to true then the function will not block for emulation suspension.
|
||||
// Defaults to false if parameter is not specified. Performing non-blocking suspension
|
||||
// is mostly useful for starting certain non-Emu related gui activities (improves gui
|
||||
// responsiveness).
|
||||
//
|
||||
void CoreEmuThread::Suspend( bool isBlocking )
|
||||
{
|
||||
{
|
||||
ScopedLock locker( m_lock_ExecMode );
|
||||
|
||||
if( (m_ExecMode == ExecMode_Suspended) || (m_ExecMode == ExecMode_Idle) )
|
||||
return;
|
||||
|
||||
if( m_ExecMode == ExecMode_Running )
|
||||
m_ExecMode = ExecMode_Suspending;
|
||||
|
||||
DevAssert( m_ExecMode == ExecMode_Suspending, "ExecMode should be nothing other than Suspended..." );
|
||||
}
|
||||
|
||||
m_SuspendEvent.Wait();
|
||||
}
|
||||
|
||||
// Applies a full suite of new settings, which will automatically facilitate the necessary
|
||||
// resets of the core and components (including plugins, if needed). The scope of resetting
|
||||
// is determined by comparing the current settings against the new settings.
|
||||
void CoreEmuThread::ApplySettings( const Pcsx2Config& src )
|
||||
{
|
||||
m_resetRecompilers = ( src.Cpu != EmuConfig.Cpu ) || ( src.Gamefixes != EmuConfig.Gamefixes ) || ( src.Speedhacks != EmuConfig.Speedhacks );
|
||||
m_resetProfilers = (src.Profiler != EmuConfig.Profiler );
|
||||
EmuConfig = src;
|
||||
}
|
||||
|
|
|
@ -1,91 +1,91 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/Threading.h"
|
||||
|
||||
using namespace Threading;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CoreEmuThread
|
||||
//
|
||||
class CoreEmuThread : public PersistentThread
|
||||
{
|
||||
public:
|
||||
enum ExecutionMode
|
||||
{
|
||||
ExecMode_Idle,
|
||||
ExecMode_Running,
|
||||
ExecMode_Suspending,
|
||||
ExecMode_Suspended
|
||||
};
|
||||
|
||||
protected:
|
||||
volatile ExecutionMode m_ExecMode;
|
||||
volatile bool m_Done;
|
||||
|
||||
Semaphore m_ResumeEvent;
|
||||
Semaphore m_SuspendEvent;
|
||||
|
||||
bool m_resetRecompilers;
|
||||
bool m_resetProfilers;
|
||||
|
||||
wxString m_elf_file;
|
||||
|
||||
MutexLock m_lock_elf_file;
|
||||
MutexLock m_lock_ExecMode;
|
||||
|
||||
public:
|
||||
static CoreEmuThread& Get();
|
||||
|
||||
public:
|
||||
CoreEmuThread() :
|
||||
m_ExecMode( ExecMode_Idle )
|
||||
, m_Done( false )
|
||||
, m_ResumeEvent()
|
||||
, m_SuspendEvent()
|
||||
, m_resetRecompilers( false )
|
||||
, m_resetProfilers( false )
|
||||
|
||||
, m_elf_file()
|
||||
, m_lock_elf_file()
|
||||
, m_lock_ExecMode()
|
||||
{
|
||||
}
|
||||
|
||||
void SetElfFile( const wxString& text )
|
||||
{
|
||||
ScopedLock lock( m_lock_elf_file );
|
||||
m_elf_file = text;
|
||||
}
|
||||
|
||||
void Start();
|
||||
void Reset();
|
||||
|
||||
bool IsSuspended() const { return (m_ExecMode == ExecMode_Suspended); }
|
||||
void Suspend( bool isBlocking = true );
|
||||
void Resume();
|
||||
void ApplySettings( const Pcsx2Config& src );
|
||||
|
||||
void StateCheck();
|
||||
|
||||
protected:
|
||||
void CpuInitializeMess();
|
||||
sptr ExecuteTask();
|
||||
};
|
||||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Utilities/Threading.h"
|
||||
|
||||
using namespace Threading;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CoreEmuThread
|
||||
//
|
||||
class CoreEmuThread : public PersistentThread
|
||||
{
|
||||
public:
|
||||
enum ExecutionMode
|
||||
{
|
||||
ExecMode_Idle,
|
||||
ExecMode_Running,
|
||||
ExecMode_Suspending,
|
||||
ExecMode_Suspended
|
||||
};
|
||||
|
||||
protected:
|
||||
volatile ExecutionMode m_ExecMode;
|
||||
volatile bool m_Done;
|
||||
|
||||
Semaphore m_ResumeEvent;
|
||||
Semaphore m_SuspendEvent;
|
||||
|
||||
bool m_resetRecompilers;
|
||||
bool m_resetProfilers;
|
||||
|
||||
wxString m_elf_file;
|
||||
|
||||
MutexLock m_lock_elf_file;
|
||||
MutexLock m_lock_ExecMode;
|
||||
|
||||
public:
|
||||
static CoreEmuThread& Get();
|
||||
|
||||
public:
|
||||
CoreEmuThread() :
|
||||
m_ExecMode( ExecMode_Idle )
|
||||
, m_Done( false )
|
||||
, m_ResumeEvent()
|
||||
, m_SuspendEvent()
|
||||
, m_resetRecompilers( false )
|
||||
, m_resetProfilers( false )
|
||||
|
||||
, m_elf_file()
|
||||
, m_lock_elf_file()
|
||||
, m_lock_ExecMode()
|
||||
{
|
||||
}
|
||||
|
||||
void SetElfFile( const wxString& text )
|
||||
{
|
||||
ScopedLock lock( m_lock_elf_file );
|
||||
m_elf_file = text;
|
||||
}
|
||||
|
||||
void Start();
|
||||
void Reset();
|
||||
|
||||
bool IsSuspended() const { return (m_ExecMode == ExecMode_Suspended); }
|
||||
void Suspend( bool isBlocking = true );
|
||||
void Resume();
|
||||
void ApplySettings( const Pcsx2Config& src );
|
||||
|
||||
void StateCheck();
|
||||
|
||||
protected:
|
||||
void CpuInitializeMess();
|
||||
sptr ExecuteTask();
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue