mirror of https://github.com/PCSX2/pcsx2.git
* Re-implemented memorycard ejection (yay!) -- helps avoid memorycard corruption when using savestates on many games (due to them caching memorycard contents).
* Memorycard settings are now applied on-the-fly (can add/remove/disable memory cards in the BIOS browser and it'll act just as if you plugged or unplugged cards on a real PS2) * Bugfixed memorycard creation dialog; which wasn't creating the memorycards in the right place (oops). * Removed the CWD option from the first time wizard (was redundant since adding the custom location option). git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3081 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
9708f279e0
commit
24e70bd524
|
@ -450,7 +450,7 @@ typedef struct _PS2E_VersionInfo
|
||||||
// PS2E_SessionInfo
|
// PS2E_SessionInfo
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// This struct is populated by the emulator prior to starting emulation, and is passed to
|
// This struct is populated by the emulator prior to starting emulation, and is passed to
|
||||||
// each plugin via a call to PS2E_PluginLibAPI::EmuStart().
|
// each plugin via a call to PS2E_PluginLibAPI::EmuOpen().
|
||||||
//
|
//
|
||||||
typedef struct _PS2E_SessionInfo
|
typedef struct _PS2E_SessionInfo
|
||||||
{
|
{
|
||||||
|
@ -649,7 +649,7 @@ typedef struct _PS2E_FreezeData
|
||||||
//
|
//
|
||||||
typedef struct _PS2E_ComponentAPI
|
typedef struct _PS2E_ComponentAPI
|
||||||
{
|
{
|
||||||
// EmuStart
|
// EmuOpen
|
||||||
// This function is called by the emulator when an emulation session is started. The
|
// This function is called by the emulator when an emulation session is started. The
|
||||||
// plugin should take this opportunity to bind itself to the given window handle, open
|
// plugin should take this opportunity to bind itself to the given window handle, open
|
||||||
// necessary audio/video/input devices, etc.
|
// necessary audio/video/input devices, etc.
|
||||||
|
@ -658,14 +658,14 @@ typedef struct _PS2E_ComponentAPI
|
||||||
// session - provides relevant emulation session information. Provided pointer is
|
// session - provides relevant emulation session information. Provided pointer is
|
||||||
// valid until after the subsequent call to EmuClose()
|
// valid until after the subsequent call to EmuClose()
|
||||||
//
|
//
|
||||||
// Threading: EmuStart is called from the GUI thread. All other emulation threads are
|
// Threading: EmuOpen is called from the GUI thread. All other emulation threads are
|
||||||
// guaranteed to be suspended or closed at the time of this call (no locks required).
|
// guaranteed to be suspended or closed at the time of this call (no locks required).
|
||||||
//
|
//
|
||||||
void (PS2E_CALLBACK* EmuStart)( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session );
|
void (PS2E_CALLBACK* EmuOpen)( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session );
|
||||||
|
|
||||||
// EmuClose
|
// EmuClose
|
||||||
// This function is called by the emulator prior to stopping emulation. The window
|
// This function is called by the emulator prior to stopping emulation. The window
|
||||||
// handle specified in EmuStart is guaranteed to be valid at the time EmuClose is called,
|
// handle specified in EmuOpen is guaranteed to be valid at the time EmuClose is called,
|
||||||
// and the plugin should unload/unbind all window dependencies at this time.
|
// and the plugin should unload/unbind all window dependencies at this time.
|
||||||
//
|
//
|
||||||
// Threading: EmuClose is called from the GUI thread. All other emulation threads are
|
// Threading: EmuClose is called from the GUI thread. All other emulation threads are
|
||||||
|
@ -691,7 +691,7 @@ typedef struct _PS2E_ComponentAPI
|
||||||
// This function should make a complete copy of the plugin's emulation state into the
|
// This function should make a complete copy of the plugin's emulation state into the
|
||||||
// provided dest->Data pointer. The plugin is allowed to reduce the dest->Size value
|
// provided dest->Data pointer. The plugin is allowed to reduce the dest->Size value
|
||||||
// but is not allowed to make it larger. The plugin will only receive calls to Freeze
|
// but is not allowed to make it larger. The plugin will only receive calls to Freeze
|
||||||
// and Thaw while a plugin is in an EmuStart() state.
|
// and Thaw while a plugin is in an EmuOpen() state.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// dest - a pointer to the Data/Size destination buffer (never NULL).
|
// dest - a pointer to the Data/Size destination buffer (never NULL).
|
||||||
|
@ -704,7 +704,7 @@ typedef struct _PS2E_ComponentAPI
|
||||||
|
|
||||||
// Thaw
|
// Thaw
|
||||||
// Plugin should restore a complete emulation state from the given FreezeData. The
|
// Plugin should restore a complete emulation state from the given FreezeData. The
|
||||||
// plugin will only receive calls to Freeze and Thaw while a plugin is in an EmuStart()
|
// plugin will only receive calls to Freeze and Thaw while a plugin is in an EmuOpen()
|
||||||
// state.
|
// state.
|
||||||
//
|
//
|
||||||
// Thread Safety:
|
// Thread Safety:
|
||||||
|
@ -719,10 +719,10 @@ typedef struct _PS2E_ComponentAPI
|
||||||
// this plugin is grayed out.
|
// this plugin is grayed out.
|
||||||
//
|
//
|
||||||
// All emulation is suspended and the plugin's state is saved to memory prior to this
|
// All emulation is suspended and the plugin's state is saved to memory prior to this
|
||||||
// function being called. Configure is only called outside the context of EmuStart()
|
// function being called. Configure is only called outside the context of EmuOpen()
|
||||||
// (after a call to EmuClose()).
|
// (after a call to EmuClose()).
|
||||||
//
|
//
|
||||||
// Plugin authors should ensure to re-read and re-apply all settings on EmuStart(),
|
// Plugin authors should ensure to re-read and re-apply all settings on EmuOpen(),
|
||||||
// which will ensure that any user changes will be applied immediately. For changes
|
// which will ensure that any user changes will be applied immediately. For changes
|
||||||
// that can be applied without emulation suspension, see/use the GUI extensions for
|
// that can be applied without emulation suspension, see/use the GUI extensions for
|
||||||
// menu and toolbar shortcuts.
|
// menu and toolbar shortcuts.
|
||||||
|
|
|
@ -23,6 +23,8 @@ BEGIN_DECLARE_EVENT_TYPES()
|
||||||
DECLARE_EVENT_TYPE( pxEvt_SynchronousCommand, -1 )
|
DECLARE_EVENT_TYPE( pxEvt_SynchronousCommand, -1 )
|
||||||
END_DECLARE_EVENT_TYPES()
|
END_DECLARE_EVENT_TYPES()
|
||||||
|
|
||||||
|
typedef void FnType_Void();
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// SynchronousActionState
|
// SynchronousActionState
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -41,8 +41,6 @@ public:
|
||||||
virtual void OnActionButtonClicked( wxCommandEvent& evt );
|
virtual void OnActionButtonClicked( wxCommandEvent& evt );
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void FnType_Void();
|
|
||||||
|
|
||||||
typedef std::list<wxEvent*> wxEventList;
|
typedef std::list<wxEvent*> wxEventList;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1020,6 +1020,17 @@ bool PluginManager::OpenPlugin_FW()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PluginManager::OpenPlugin_Mcd()
|
||||||
|
{
|
||||||
|
ScopedLock lock( m_mtx_PluginStatus );
|
||||||
|
|
||||||
|
// [TODO] Fix up and implement PS2E_SessionInfo here!! (the currently NULL parameter)
|
||||||
|
if( SysPlugins.Mcd )
|
||||||
|
SysPlugins.Mcd->Base.EmuOpen( (PS2E_THISPTR) SysPlugins.Mcd, NULL );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void PluginManager::Open( PluginsEnum_t pid )
|
void PluginManager::Open( PluginsEnum_t pid )
|
||||||
{
|
{
|
||||||
pxAssume( (uint)pid < PluginId_Count );
|
pxAssume( (uint)pid < PluginId_Count );
|
||||||
|
@ -1039,6 +1050,7 @@ void PluginManager::Open( PluginsEnum_t pid )
|
||||||
case PluginId_USB: result = OpenPlugin_USB(); break;
|
case PluginId_USB: result = OpenPlugin_USB(); break;
|
||||||
case PluginId_FW: result = OpenPlugin_FW(); break;
|
case PluginId_FW: result = OpenPlugin_FW(); break;
|
||||||
case PluginId_DEV9: result = OpenPlugin_DEV9(); break;
|
case PluginId_DEV9: result = OpenPlugin_DEV9(); break;
|
||||||
|
|
||||||
jNO_DEFAULT;
|
jNO_DEFAULT;
|
||||||
}
|
}
|
||||||
if( !result )
|
if( !result )
|
||||||
|
@ -1068,6 +1080,12 @@ void PluginManager::Open()
|
||||||
|
|
||||||
if (GSopen2) GetMTGS().WaitForOpen();
|
if (GSopen2) GetMTGS().WaitForOpen();
|
||||||
|
|
||||||
|
if( !AtomicExchange( m_mcdOpen, true ) )
|
||||||
|
{
|
||||||
|
DbgCon.Indent().WriteLn( "Opening Memorycards");
|
||||||
|
OpenPlugin_Mcd();
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLn( Color_StrongBlue, "Plugins opened successfully." );
|
Console.WriteLn( Color_StrongBlue, "Plugins opened successfully." );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,6 +1138,11 @@ void PluginManager::ClosePlugin_FW()
|
||||||
_generalclose( PluginId_FW );
|
_generalclose( PluginId_FW );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PluginManager::ClosePlugin_Mcd()
|
||||||
|
{
|
||||||
|
ScopedLock lock( m_mtx_PluginStatus );
|
||||||
|
if( SysPlugins.Mcd ) SysPlugins.Mcd->Base.EmuClose( (PS2E_THISPTR) SysPlugins.Mcd );
|
||||||
|
}
|
||||||
|
|
||||||
void PluginManager::Close( PluginsEnum_t pid )
|
void PluginManager::Close( PluginsEnum_t pid )
|
||||||
{
|
{
|
||||||
|
@ -1139,6 +1162,7 @@ void PluginManager::Close( PluginsEnum_t pid )
|
||||||
case PluginId_USB: ClosePlugin_USB(); break;
|
case PluginId_USB: ClosePlugin_USB(); break;
|
||||||
case PluginId_FW: ClosePlugin_FW(); break;
|
case PluginId_FW: ClosePlugin_FW(); break;
|
||||||
case PluginId_DEV9: ClosePlugin_DEV9(); break;
|
case PluginId_DEV9: ClosePlugin_DEV9(); break;
|
||||||
|
case PluginId_Mcd: ClosePlugin_Mcd(); break;
|
||||||
|
|
||||||
jNO_DEFAULT;
|
jNO_DEFAULT;
|
||||||
}
|
}
|
||||||
|
@ -1156,6 +1180,12 @@ void PluginManager::Close()
|
||||||
|
|
||||||
DbgCon.WriteLn( Color_StrongBlue, "Closing plugins..." );
|
DbgCon.WriteLn( Color_StrongBlue, "Closing plugins..." );
|
||||||
|
|
||||||
|
if( AtomicExchange( m_mcdOpen, false ) )
|
||||||
|
{
|
||||||
|
DbgCon.Indent().WriteLn( "Closing Memorycards");
|
||||||
|
ClosePlugin_Mcd();
|
||||||
|
}
|
||||||
|
|
||||||
for( int i=PluginId_Count-1; i>=0; --i )
|
for( int i=PluginId_Count-1; i>=0; --i )
|
||||||
Close( tbl_PluginInfo[i].id );
|
Close( tbl_PluginInfo[i].id );
|
||||||
|
|
||||||
|
|
|
@ -268,6 +268,9 @@ protected:
|
||||||
wxString m_SettingsFolder;
|
wxString m_SettingsFolder;
|
||||||
Threading::MutexRecursive m_mtx_PluginStatus;
|
Threading::MutexRecursive m_mtx_PluginStatus;
|
||||||
|
|
||||||
|
// Lovely hack until the new PS2E API is completed.
|
||||||
|
volatile u32 m_mcdOpen;
|
||||||
|
|
||||||
public: // hack until we unsuck plugins...
|
public: // hack until we unsuck plugins...
|
||||||
ScopedPtr<PluginStatus_t> m_info[PluginId_Count];
|
ScopedPtr<PluginStatus_t> m_info[PluginId_Count];
|
||||||
|
|
||||||
|
@ -327,6 +330,7 @@ protected:
|
||||||
virtual bool OpenPlugin_DEV9();
|
virtual bool OpenPlugin_DEV9();
|
||||||
virtual bool OpenPlugin_USB();
|
virtual bool OpenPlugin_USB();
|
||||||
virtual bool OpenPlugin_FW();
|
virtual bool OpenPlugin_FW();
|
||||||
|
virtual bool OpenPlugin_Mcd();
|
||||||
|
|
||||||
void _generalclose( PluginsEnum_t pid );
|
void _generalclose( PluginsEnum_t pid );
|
||||||
|
|
||||||
|
@ -337,6 +341,7 @@ protected:
|
||||||
virtual void ClosePlugin_DEV9();
|
virtual void ClosePlugin_DEV9();
|
||||||
virtual void ClosePlugin_USB();
|
virtual void ClosePlugin_USB();
|
||||||
virtual void ClosePlugin_FW();
|
virtual void ClosePlugin_FW();
|
||||||
|
virtual void ClosePlugin_Mcd();
|
||||||
|
|
||||||
friend class SysMtgsThread;
|
friend class SysMtgsThread;
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,7 +26,9 @@ static const u8 cardh[4] = { 0xFF, 0xFF, 0x5a, 0x5d };
|
||||||
// Memory Card Specs : Sector size etc.
|
// Memory Card Specs : Sector size etc.
|
||||||
static const mc_command_0x26_tag mc_command_0x26= {'+', 512, 16, 0x4000, 0x52, 0x5A};
|
static const mc_command_0x26_tag mc_command_0x26= {'+', 512, 16, 0x4000, 0x52, 0x5A};
|
||||||
|
|
||||||
static int m_PostSavestateCards[2] = { 0, 0 };
|
// Ejection timeout management belongs in the MemoryCardFile plugin, except the plugin
|
||||||
|
// interface is not yet complete.
|
||||||
|
static int m_ForceEjectionTimeout[2];
|
||||||
|
|
||||||
// SIO Inline'd IRQs : Calls the SIO interrupt handlers directly instead of
|
// SIO Inline'd IRQs : Calls the SIO interrupt handlers directly instead of
|
||||||
// feeding them through the IOP's branch test. (see SIO.H for details)
|
// feeding them through the IOP's branch test. (see SIO.H for details)
|
||||||
|
@ -88,7 +90,7 @@ static u8 sio_xor( const u8 *buf, uint length )
|
||||||
void sioInit()
|
void sioInit()
|
||||||
{
|
{
|
||||||
memzero(sio);
|
memzero(sio);
|
||||||
memzero(m_PostSavestateCards);
|
memzero(m_ForceEjectionTimeout);
|
||||||
|
|
||||||
// Transfer(?) Ready and the Buffer is Empty
|
// Transfer(?) Ready and the Buffer is Empty
|
||||||
sio.StatReg = TX_RDY | TX_EMPTY;
|
sio.StatReg = TX_RDY | TX_EMPTY;
|
||||||
|
@ -602,7 +604,18 @@ void InitializeSIO(u8 value)
|
||||||
const uint port = sio.GetMemcardIndex();
|
const uint port = sio.GetMemcardIndex();
|
||||||
const uint slot = sio.activeMemcardSlot[port];
|
const uint slot = sio.activeMemcardSlot[port];
|
||||||
|
|
||||||
if( SysPlugins.McdIsPresent( port, slot ) )
|
// forced ejection logic. Technically belongs in the McdIsPresent handler for
|
||||||
|
// the plugin, once the memorycard plugin system is completed.
|
||||||
|
// (ejection is only supported for the default non-multitap cards at this time)
|
||||||
|
|
||||||
|
bool forceEject = false;
|
||||||
|
if( slot == 0 && m_ForceEjectionTimeout[port] )
|
||||||
|
{
|
||||||
|
--m_ForceEjectionTimeout[port];
|
||||||
|
forceEject = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !forceEject && SysPlugins.McdIsPresent( port, slot ) )
|
||||||
{
|
{
|
||||||
sio2.packet.recvVal1 = 0x1100;
|
sio2.packet.recvVal1 = 0x1100;
|
||||||
PAD_LOG("START MEMCARD [port:%d, slot:%d] - Present", port, slot );
|
PAD_LOG("START MEMCARD [port:%d, slot:%d] - Present", port, slot );
|
||||||
|
@ -654,19 +667,29 @@ void SaveStateBase::sioFreeze()
|
||||||
FreezeTag( "sio" );
|
FreezeTag( "sio" );
|
||||||
Freeze( sio );
|
Freeze( sio );
|
||||||
|
|
||||||
|
// TODO : This stuff should all be moved to the memorycard plugin eventually,
|
||||||
|
// but that requires adding memorycard plugin to the savestate, and I'm not in
|
||||||
|
// the mood to do that (let's plan it for 0.9.8) --air
|
||||||
|
|
||||||
|
// Note: The Ejection system only works for the default non-multitap MemoryCards
|
||||||
|
// only. This is because it could become very (very!) slow to do a full CRC check
|
||||||
|
// on multiple 32 or 64 meg carts. I have chosen to save
|
||||||
|
|
||||||
if( IsSaving() )
|
if( IsSaving() )
|
||||||
{
|
{
|
||||||
for( int port=0; port<2; ++port )
|
for( uint port=0; port<2; ++port )
|
||||||
|
//for( uint slot=0; slot<4; ++slot )
|
||||||
{
|
{
|
||||||
for( int slot=0; slot<4; ++slot )
|
const int slot = 0; // see above comment about multitap slowness
|
||||||
m_mcdCRCs[port][slot] = SysPlugins.McdGetCRC( port, slot );
|
m_mcdCRCs[port][slot] = SysPlugins.McdGetCRC( port, slot );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Freeze( m_mcdCRCs );
|
Freeze( m_mcdCRCs );
|
||||||
|
|
||||||
if( IsLoading() && EmuConfig.McdEnableEjection )
|
if( IsLoading() && EmuConfig.McdEnableEjection )
|
||||||
{
|
{
|
||||||
// Notes:
|
// Notes on the ForceEjectionTimeout:
|
||||||
// * TOTA works with values as low as 20 here.
|
// * TOTA works with values as low as 20 here.
|
||||||
// It "times out" with values around 1800 (forces user to check the memcard
|
// It "times out" with values around 1800 (forces user to check the memcard
|
||||||
// twice to find it). Other games could be different. :|
|
// twice to find it). Other games could be different. :|
|
||||||
|
@ -680,14 +703,14 @@ void SaveStateBase::sioFreeze()
|
||||||
// ejecting it, the game freezes (which is actually good emulation, but annoying!)
|
// ejecting it, the game freezes (which is actually good emulation, but annoying!)
|
||||||
|
|
||||||
for( int port=0; port<2; ++port )
|
for( int port=0; port<2; ++port )
|
||||||
|
//for( int slot=0; slot<4; ++slot )
|
||||||
{
|
{
|
||||||
for( int slot=0; slot<4; ++slot )
|
const int slot = 0; // see above comment about multitap slowness
|
||||||
{
|
|
||||||
u64 newCRC = SysPlugins.McdGetCRC( port, slot );
|
u64 newCRC = SysPlugins.McdGetCRC( port, slot );
|
||||||
if( newCRC != m_mcdCRCs[port][slot] )
|
if( newCRC != m_mcdCRCs[port][slot] )
|
||||||
{
|
{
|
||||||
m_mcdCRCs[port][slot] = newCRC;
|
//m_mcdCRCs[port][slot] = newCRC;
|
||||||
}
|
m_ForceEjectionTimeout[port] = 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace PathDefs
|
||||||
switch( mode )
|
switch( mode )
|
||||||
{
|
{
|
||||||
case DocsFolder_User: return (wxDirName)Path::Combine( wxStandardPaths::Get().GetDocumentsDir(), wxGetApp().GetAppName() );
|
case DocsFolder_User: return (wxDirName)Path::Combine( wxStandardPaths::Get().GetDocumentsDir(), wxGetApp().GetAppName() );
|
||||||
case DocsFolder_CWD: return (wxDirName)wxGetCwd();
|
//case DocsFolder_CWD: return (wxDirName)wxGetCwd();
|
||||||
case DocsFolder_Custom: return CustomDocumentsFolder;
|
case DocsFolder_Custom: return CustomDocumentsFolder;
|
||||||
|
|
||||||
jNO_DEFAULT
|
jNO_DEFAULT
|
||||||
|
@ -561,7 +561,7 @@ void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
|
||||||
{
|
{
|
||||||
ApplyDefaults();
|
ApplyDefaults();
|
||||||
|
|
||||||
if( DocsFolderMode != DocsFolder_CWD )
|
//if( DocsFolderMode != DocsFolder_CWD )
|
||||||
{
|
{
|
||||||
for( int i=0; i<FolderId_COUNT; ++i )
|
for( int i=0; i<FolderId_COUNT; ++i )
|
||||||
operator[]( (FoldersEnum_t)i ).Normalize();
|
operator[]( (FoldersEnum_t)i ).Normalize();
|
||||||
|
@ -719,7 +719,7 @@ void RelocateLogfile()
|
||||||
//
|
//
|
||||||
void AppConfig_OnChangedSettingsFolder( bool overwrite )
|
void AppConfig_OnChangedSettingsFolder( bool overwrite )
|
||||||
{
|
{
|
||||||
if( DocsFolderMode != DocsFolder_CWD )
|
//if( DocsFolderMode != DocsFolder_CWD )
|
||||||
PathDefs::GetDocuments().Mkdir();
|
PathDefs::GetDocuments().Mkdir();
|
||||||
|
|
||||||
GetSettingsFolder().Mkdir();
|
GetSettingsFolder().Mkdir();
|
||||||
|
|
|
@ -25,7 +25,7 @@ enum DocsModeType
|
||||||
DocsFolder_User,
|
DocsFolder_User,
|
||||||
|
|
||||||
// uses the current working directory for program data
|
// uses the current working directory for program data
|
||||||
DocsFolder_CWD,
|
//DocsFolder_CWD,
|
||||||
|
|
||||||
// uses a custom location for program data
|
// uses a custom location for program data
|
||||||
DocsFolder_Custom,
|
DocsFolder_Custom,
|
||||||
|
|
|
@ -500,8 +500,10 @@ void SysExecEvent_SaveSinglePlugin::InvokeEvent()
|
||||||
s_DisableGsWindow = true; // keeps the GS window smooth by avoiding closing the window
|
s_DisableGsWindow = true; // keeps the GS window smooth by avoiding closing the window
|
||||||
|
|
||||||
ScopedCoreThreadPause paused_core;
|
ScopedCoreThreadPause paused_core;
|
||||||
_LoadPluginsImmediate();
|
//_LoadPluginsImmediate();
|
||||||
|
|
||||||
|
if( CorePlugins.AreLoaded() )
|
||||||
|
{
|
||||||
ScopedPtr<VmStateBuffer> plugstore;
|
ScopedPtr<VmStateBuffer> plugstore;
|
||||||
|
|
||||||
if( CoreThread.HasActiveMachine() )
|
if( CoreThread.HasActiveMachine() )
|
||||||
|
@ -521,6 +523,7 @@ void SysExecEvent_SaveSinglePlugin::InvokeEvent()
|
||||||
GetCorePlugins().Freeze( m_pid, load );
|
GetCorePlugins().Freeze( m_pid, load );
|
||||||
GetCorePlugins().Close( m_pid ); // hack for stupid GS plugins.
|
GetCorePlugins().Close( m_pid ); // hack for stupid GS plugins.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s_DisableGsWindow = false;
|
s_DisableGsWindow = false;
|
||||||
paused_core.AllowResume();
|
paused_core.AllowResume();
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "System/SysThreads.h"
|
#include "System/SysThreads.h"
|
||||||
|
#include "pxEventThread.h"
|
||||||
|
|
||||||
#include "AppCommon.h"
|
#include "AppCommon.h"
|
||||||
#include "AppCorePlugins.h"
|
#include "AppCorePlugins.h"
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
|
|
|
@ -170,13 +170,16 @@ void Dialogs::BaseConfigurationDialog::OnSetSettingsPage( wxCommandEvent& evt )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dialogs::BaseConfigurationDialog::SomethingChanged()
|
||||||
|
{
|
||||||
|
if( wxWindow* apply = FindWindow( wxID_APPLY ) ) apply->Enable();
|
||||||
|
}
|
||||||
|
|
||||||
void Dialogs::BaseConfigurationDialog::OnSomethingChanged( wxCommandEvent& evt )
|
void Dialogs::BaseConfigurationDialog::OnSomethingChanged( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
if( (evt.GetId() != wxID_OK) && (evt.GetId() != wxID_CANCEL) && (evt.GetId() != wxID_APPLY) )
|
if( (evt.GetId() != wxID_OK) && (evt.GetId() != wxID_CANCEL) && (evt.GetId() != wxID_APPLY) )
|
||||||
{
|
SomethingChanged();
|
||||||
if( wxWindow* apply = FindWindow( wxID_APPLY ) ) apply->Enable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,8 @@ namespace Dialogs
|
||||||
void AddListbook( wxSizer* sizer=NULL );
|
void AddListbook( wxSizer* sizer=NULL );
|
||||||
void CreateListbook( wxImageList& bookicons );
|
void CreateListbook( wxImageList& bookicons );
|
||||||
|
|
||||||
|
virtual void SomethingChanged();
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
void AddPage( const char* label, int iconid );
|
void AddPage( const char* label, int iconid );
|
||||||
|
|
||||||
|
@ -68,8 +70,8 @@ namespace Dialogs
|
||||||
void OnCloseWindow( wxCloseEvent& evt );
|
void OnCloseWindow( wxCloseEvent& evt );
|
||||||
|
|
||||||
void OnSetSettingsPage( wxCommandEvent& evt );
|
void OnSetSettingsPage( wxCommandEvent& evt );
|
||||||
|
void OnSomethingChanged( wxCommandEvent& evt );
|
||||||
|
|
||||||
virtual void OnSomethingChanged( wxCommandEvent& evt );
|
|
||||||
virtual wxString& GetConfSettingsTabName() const=0;
|
virtual wxString& GetConfSettingsTabName() const=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -73,13 +73,14 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint
|
||||||
s_padding += m_filepicker | StdExpand();
|
s_padding += m_filepicker | StdExpand();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_padding += Heading( _( "(new card will be saved to:" ) );
|
s_padding += Heading( _( "New card will be saved to:" ) );
|
||||||
s_padding += Heading( (m_mcdpath + m_mcdfile).GetFullPath() );
|
s_padding += Heading( (m_mcdpath + m_mcdfile).GetFullPath() );
|
||||||
}
|
}
|
||||||
|
|
||||||
s_padding += m_radio_CardSize | StdExpand();
|
s_padding += m_radio_CardSize | StdExpand();
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
if( m_check_CompressNTFS ) s_padding += m_check_CompressNTFS | StdExpand();
|
if( m_check_CompressNTFS )
|
||||||
|
s_padding += m_check_CompressNTFS | StdExpand();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s_padding += 12;
|
s_padding += 12;
|
||||||
|
@ -87,8 +88,6 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint
|
||||||
|
|
||||||
*this += s_padding | StdExpand();
|
*this += s_padding | StdExpand();
|
||||||
|
|
||||||
|
|
||||||
//FindItem( wxID_OK )->SetLabel(_("Create"));
|
|
||||||
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnOk_Click ) );
|
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnOk_Click ) );
|
||||||
//Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnApply_Click ) );
|
//Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnApply_Click ) );
|
||||||
}
|
}
|
||||||
|
@ -126,7 +125,7 @@ static bool CreateIt( const wxString& mcdFile, uint sizeInMB )
|
||||||
void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
|
void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
if( !CreateIt(
|
if( !CreateIt(
|
||||||
m_filepicker ? m_filepicker->GetPath() : m_mcdfile,
|
m_filepicker ? m_filepicker->GetPath() : (m_mcdpath + m_mcdfile).GetFullPath(),
|
||||||
m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8
|
m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8
|
||||||
) )
|
) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -172,6 +172,9 @@ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
|
||||||
//AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), cfgid.MemoryCard );
|
//AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), cfgid.MemoryCard );
|
||||||
//AddPage<McdConfigPanel_Standard> ( wxLt("Slots 1/2"), cfgid.MemoryCard );
|
//AddPage<McdConfigPanel_Standard> ( wxLt("Slots 1/2"), cfgid.MemoryCard );
|
||||||
|
|
||||||
|
*this += Heading(_("Drag items in the list over other items to swap or copy MemoryCards."));
|
||||||
|
*this += StdPadding;
|
||||||
|
|
||||||
*this += m_panel_mcdlist | StdExpand();
|
*this += m_panel_mcdlist | StdExpand();
|
||||||
//*this += StdPadding;
|
//*this += StdPadding;
|
||||||
*this += new wxStaticLine( this ) | StdExpand();
|
*this += new wxStaticLine( this ) | StdExpand();
|
||||||
|
|
|
@ -58,6 +58,9 @@ public:
|
||||||
void Lock();
|
void Lock();
|
||||||
void Unlock();
|
void Unlock();
|
||||||
|
|
||||||
|
void Open();
|
||||||
|
void Close();
|
||||||
|
|
||||||
s32 IsPresent ( uint slot );
|
s32 IsPresent ( uint slot );
|
||||||
s32 Read ( uint slot, u8 *dest, u32 adr, int size );
|
s32 Read ( uint slot, u8 *dest, u32 adr, int size );
|
||||||
s32 Save ( uint slot, const u8 *src, u32 adr, int size );
|
s32 Save ( uint slot, const u8 *src, u32 adr, int size );
|
||||||
|
@ -132,17 +135,44 @@ wxString FileMcd_GetDefaultName(uint slot)
|
||||||
FileMemoryCard::FileMemoryCard()
|
FileMemoryCard::FileMemoryCard()
|
||||||
{
|
{
|
||||||
memset8<0xff>( m_effeffs );
|
memset8<0xff>( m_effeffs );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileMemoryCard::Open()
|
||||||
|
{
|
||||||
for( int slot=0; slot<8; ++slot )
|
for( int slot=0; slot<8; ++slot )
|
||||||
{
|
{
|
||||||
if( !g_Conf->Mcd[slot].Enabled || g_Conf->Mcd[slot].Filename.GetFullName().IsEmpty() ) continue;
|
if( FileMcd_IsMultitapSlot(slot) )
|
||||||
|
{
|
||||||
|
if( !EmuConfig.MultitapPort0_Enabled && (FileMcd_GetMtapPort(slot) == 0) ) continue;
|
||||||
|
if( !EmuConfig.MultitapPort1_Enabled && (FileMcd_GetMtapPort(slot) == 1) ) continue;
|
||||||
|
}
|
||||||
|
|
||||||
wxFileName fname( g_Conf->FullpathToMcd( slot ) );
|
wxFileName fname( g_Conf->FullpathToMcd( slot ) );
|
||||||
wxString str( fname.GetFullPath() );
|
wxString str( fname.GetFullPath() );
|
||||||
|
bool cont = false;
|
||||||
|
|
||||||
|
if( fname.GetFullName().IsEmpty() )
|
||||||
|
{
|
||||||
|
str = L"[empty filename]";
|
||||||
|
cont = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !g_Conf->Mcd[slot].Enabled )
|
||||||
|
{
|
||||||
|
str = L"[disabled]";
|
||||||
|
cont = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLn( cont ? Color_Gray : Color_Green, L"McdSlot %u: " + str, slot );
|
||||||
|
if( cont ) continue;
|
||||||
|
|
||||||
const wxULongLong fsz = fname.GetSize();
|
const wxULongLong fsz = fname.GetSize();
|
||||||
if( (fsz == 0) || (fsz == wxInvalidSize) )
|
if( (fsz == 0) || (fsz == wxInvalidSize) )
|
||||||
{
|
{
|
||||||
|
// FIXME : Ideally this should prompt the user for the size of the
|
||||||
|
// memorycard file they would like to create, instead of trying to
|
||||||
|
// create one automatically.
|
||||||
|
|
||||||
if( !Create( str, 8 ) )
|
if( !Create( str, 8 ) )
|
||||||
{
|
{
|
||||||
Msgbox::Alert(
|
Msgbox::Alert(
|
||||||
|
@ -153,7 +183,7 @@ FileMemoryCard::FileMemoryCard()
|
||||||
}
|
}
|
||||||
|
|
||||||
// [TODO] : Add memcard size detection and report it to the console log.
|
// [TODO] : Add memcard size detection and report it to the console log.
|
||||||
// (8MB, 256Mb, whatever)
|
// (8MB, 256Mb, formatted, unformatted, etc ...)
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
NTFS_CompressFile( str, g_Conf->McdCompressNTFS );
|
NTFS_CompressFile( str, g_Conf->McdCompressNTFS );
|
||||||
|
@ -171,6 +201,12 @@ FileMemoryCard::FileMemoryCard()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileMemoryCard::Close()
|
||||||
|
{
|
||||||
|
for( int slot=0; slot<8; ++slot )
|
||||||
|
m_file[slot].Close();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns FALSE if the seek failed (is outside the bounds of the file).
|
// Returns FALSE if the seek failed (is outside the bounds of the file).
|
||||||
bool FileMemoryCard::Seek( wxFFile& f, u32 adr )
|
bool FileMemoryCard::Seek( wxFFile& f, u32 adr )
|
||||||
{
|
{
|
||||||
|
@ -308,6 +344,16 @@ uint FileMcd_ConvertToSlot( uint port, uint slot )
|
||||||
return slot + 4; // multitap 2
|
return slot + 4; // multitap 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PS2E_CALLBACK FileMcd_EmuOpen( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session )
|
||||||
|
{
|
||||||
|
thisptr->impl.Open();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PS2E_CALLBACK FileMcd_EmuClose( PS2E_THISPTR thisptr )
|
||||||
|
{
|
||||||
|
thisptr->impl.Close();
|
||||||
|
}
|
||||||
|
|
||||||
static s32 PS2E_CALLBACK FileMcd_IsPresent( PS2E_THISPTR thisptr, uint port, uint slot )
|
static s32 PS2E_CALLBACK FileMcd_IsPresent( PS2E_THISPTR thisptr, uint port, uint slot )
|
||||||
{
|
{
|
||||||
return thisptr->impl.IsPresent( FileMcd_ConvertToSlot( port, slot ) );
|
return thisptr->impl.IsPresent( FileMcd_ConvertToSlot( port, slot ) );
|
||||||
|
@ -337,6 +383,9 @@ Component_FileMcd::Component_FileMcd()
|
||||||
{
|
{
|
||||||
memzero( api );
|
memzero( api );
|
||||||
|
|
||||||
|
api.Base.EmuOpen = FileMcd_EmuOpen;
|
||||||
|
api.Base.EmuClose = FileMcd_EmuClose;
|
||||||
|
|
||||||
api.McdIsPresent = FileMcd_IsPresent;
|
api.McdIsPresent = FileMcd_IsPresent;
|
||||||
api.McdRead = FileMcd_Read;
|
api.McdRead = FileMcd_Read;
|
||||||
api.McdSave = FileMcd_Save;
|
api.McdSave = FileMcd_Save;
|
||||||
|
|
|
@ -69,6 +69,7 @@ void Panels::BaseSelectorPanel::RefreshSelections()
|
||||||
|
|
||||||
void Panels::BaseSelectorPanel::OnRefreshSelections( wxCommandEvent& evt )
|
void Panels::BaseSelectorPanel::OnRefreshSelections( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
|
evt.Skip();
|
||||||
RefreshSelections();
|
RefreshSelections();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
|
#include "AppCoreThread.h"
|
||||||
|
#include "System.h"
|
||||||
|
|
||||||
#include "ConfigurationPanels.h"
|
#include "ConfigurationPanels.h"
|
||||||
#include "MemoryCardPanels.h"
|
#include "MemoryCardPanels.h"
|
||||||
#include "System.h"
|
|
||||||
|
|
||||||
#include <wx/filepicker.h>
|
#include <wx/filepicker.h>
|
||||||
#include <wx/ffile.h>
|
#include <wx/ffile.h>
|
||||||
|
@ -491,6 +493,9 @@ void Panels::MemoryCardListPanel_Simple::Apply()
|
||||||
{
|
{
|
||||||
//_parent::Apply();
|
//_parent::Apply();
|
||||||
|
|
||||||
|
ScopedCoreThreadClose closed_core;
|
||||||
|
closed_core.AllowResume();
|
||||||
|
|
||||||
for( uint slot=0; slot<8; ++slot )
|
for( uint slot=0; slot<8; ++slot )
|
||||||
{
|
{
|
||||||
g_Conf->Mcd[slot].Enabled = m_Cards[slot].IsEnabled && m_Cards[slot].IsPresent;
|
g_Conf->Mcd[slot].Enabled = m_Cards[slot].IsEnabled && m_Cards[slot].IsPresent;
|
||||||
|
@ -581,6 +586,8 @@ void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
|
||||||
|
|
||||||
void Panels::MemoryCardListPanel_Simple::OnMountCard(wxCommandEvent& evt)
|
void Panels::MemoryCardListPanel_Simple::OnMountCard(wxCommandEvent& evt)
|
||||||
{
|
{
|
||||||
|
evt.Skip();
|
||||||
|
|
||||||
const int sel = m_listview->GetFirstSelected();
|
const int sel = m_listview->GetFirstSelected();
|
||||||
if( wxNOT_FOUND == sel ) return;
|
if( wxNOT_FOUND == sel ) return;
|
||||||
const uint slot = sel;
|
const uint slot = sel;
|
||||||
|
|
|
@ -51,12 +51,6 @@ Panels::DocsFolderPickerPanel::DocsFolderPickerPanel( wxWindow* parent, bool isF
|
||||||
_("Location: ") + wxStandardPaths::Get().GetDocumentsDir()
|
_("Location: ") + wxStandardPaths::Get().GetDocumentsDir()
|
||||||
),
|
),
|
||||||
|
|
||||||
RadioPanelItem(
|
|
||||||
_("Current working folder (intended for developer use only)"),
|
|
||||||
_("Location: ") + wxGetCwd(),
|
|
||||||
_("This setting requires administration privileges from your operating system.")
|
|
||||||
),
|
|
||||||
|
|
||||||
RadioPanelItem(
|
RadioPanelItem(
|
||||||
_("Custom folder:"),
|
_("Custom folder:"),
|
||||||
wxEmptyString,
|
wxEmptyString,
|
||||||
|
|
|
@ -672,7 +672,7 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
|
||||||
else if( m_ComponentBoxes->Get(pid).GetSelection() == wxNOT_FOUND )
|
else if( m_ComponentBoxes->Get(pid).GetSelection() == wxNOT_FOUND )
|
||||||
{
|
{
|
||||||
m_ComponentBoxes->Get(pid).SetSelection( 0 );
|
m_ComponentBoxes->Get(pid).SetSelection( 0 );
|
||||||
m_ComponentBoxes->GetConfigButton(pid).Enable( CorePlugins.AreLoaded() );
|
m_ComponentBoxes->GetConfigButton(pid).Enable( !CorePlugins.AreLoaded() );
|
||||||
}
|
}
|
||||||
} while( ++pi, pi->shortname != NULL );
|
} while( ++pi, pi->shortname != NULL );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue