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
|
||||
// --------------------------------------------------------------------------------------
|
||||
// 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
|
||||
{
|
||||
|
@ -649,7 +649,7 @@ typedef struct _PS2E_FreezeData
|
|||
//
|
||||
typedef struct _PS2E_ComponentAPI
|
||||
{
|
||||
// EmuStart
|
||||
// EmuOpen
|
||||
// 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
|
||||
// necessary audio/video/input devices, etc.
|
||||
|
@ -658,14 +658,14 @@ typedef struct _PS2E_ComponentAPI
|
|||
// session - provides relevant emulation session information. Provided pointer is
|
||||
// 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).
|
||||
//
|
||||
void (PS2E_CALLBACK* EmuStart)( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session );
|
||||
void (PS2E_CALLBACK* EmuOpen)( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session );
|
||||
|
||||
// EmuClose
|
||||
// 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.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// and Thaw while a plugin is in an EmuStart() state.
|
||||
// and Thaw while a plugin is in an EmuOpen() state.
|
||||
//
|
||||
// Parameters:
|
||||
// dest - a pointer to the Data/Size destination buffer (never NULL).
|
||||
|
@ -704,7 +704,7 @@ typedef struct _PS2E_ComponentAPI
|
|||
|
||||
// Thaw
|
||||
// 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.
|
||||
//
|
||||
// Thread Safety:
|
||||
|
@ -719,10 +719,10 @@ typedef struct _PS2E_ComponentAPI
|
|||
// this plugin is grayed out.
|
||||
//
|
||||
// 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()).
|
||||
//
|
||||
// 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
|
||||
// that can be applied without emulation suspension, see/use the GUI extensions for
|
||||
// menu and toolbar shortcuts.
|
||||
|
|
|
@ -23,6 +23,8 @@ BEGIN_DECLARE_EVENT_TYPES()
|
|||
DECLARE_EVENT_TYPE( pxEvt_SynchronousCommand, -1 )
|
||||
END_DECLARE_EVENT_TYPES()
|
||||
|
||||
typedef void FnType_Void();
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// SynchronousActionState
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -41,8 +41,6 @@ public:
|
|||
virtual void OnActionButtonClicked( wxCommandEvent& evt );
|
||||
};
|
||||
|
||||
typedef void FnType_Void();
|
||||
|
||||
typedef std::list<wxEvent*> wxEventList;
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -1020,6 +1020,17 @@ bool PluginManager::OpenPlugin_FW()
|
|||
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 )
|
||||
{
|
||||
pxAssume( (uint)pid < PluginId_Count );
|
||||
|
@ -1039,6 +1050,7 @@ void PluginManager::Open( PluginsEnum_t pid )
|
|||
case PluginId_USB: result = OpenPlugin_USB(); break;
|
||||
case PluginId_FW: result = OpenPlugin_FW(); break;
|
||||
case PluginId_DEV9: result = OpenPlugin_DEV9(); break;
|
||||
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
if( !result )
|
||||
|
@ -1068,6 +1080,12 @@ void PluginManager::Open()
|
|||
|
||||
if (GSopen2) GetMTGS().WaitForOpen();
|
||||
|
||||
if( !AtomicExchange( m_mcdOpen, true ) )
|
||||
{
|
||||
DbgCon.Indent().WriteLn( "Opening Memorycards");
|
||||
OpenPlugin_Mcd();
|
||||
}
|
||||
|
||||
Console.WriteLn( Color_StrongBlue, "Plugins opened successfully." );
|
||||
}
|
||||
|
||||
|
@ -1120,6 +1138,11 @@ void PluginManager::ClosePlugin_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 )
|
||||
{
|
||||
|
@ -1139,6 +1162,7 @@ void PluginManager::Close( PluginsEnum_t pid )
|
|||
case PluginId_USB: ClosePlugin_USB(); break;
|
||||
case PluginId_FW: ClosePlugin_FW(); break;
|
||||
case PluginId_DEV9: ClosePlugin_DEV9(); break;
|
||||
case PluginId_Mcd: ClosePlugin_Mcd(); break;
|
||||
|
||||
jNO_DEFAULT;
|
||||
}
|
||||
|
@ -1156,9 +1180,15 @@ void PluginManager::Close()
|
|||
|
||||
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 )
|
||||
Close( tbl_PluginInfo[i].id );
|
||||
|
||||
|
||||
DbgCon.WriteLn( Color_StrongBlue, "Plugins closed successfully." );
|
||||
}
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ public:
|
|||
void McdRead( uint port, uint slot, u8 *dest, u32 adr, int size );
|
||||
void McdSave( uint port, uint slot, const u8 *src, u32 adr, int size );
|
||||
void McdEraseBlock( uint port, uint slot, u32 adr );
|
||||
u64 McdGetCRC( uint port, uint slot );
|
||||
u64 McdGetCRC( uint port, uint slot );
|
||||
|
||||
friend class PluginManager;
|
||||
};
|
||||
|
@ -268,6 +268,9 @@ protected:
|
|||
wxString m_SettingsFolder;
|
||||
Threading::MutexRecursive m_mtx_PluginStatus;
|
||||
|
||||
// Lovely hack until the new PS2E API is completed.
|
||||
volatile u32 m_mcdOpen;
|
||||
|
||||
public: // hack until we unsuck plugins...
|
||||
ScopedPtr<PluginStatus_t> m_info[PluginId_Count];
|
||||
|
||||
|
@ -327,7 +330,8 @@ protected:
|
|||
virtual bool OpenPlugin_DEV9();
|
||||
virtual bool OpenPlugin_USB();
|
||||
virtual bool OpenPlugin_FW();
|
||||
|
||||
virtual bool OpenPlugin_Mcd();
|
||||
|
||||
void _generalclose( PluginsEnum_t pid );
|
||||
|
||||
virtual void ClosePlugin_GS();
|
||||
|
@ -337,6 +341,7 @@ protected:
|
|||
virtual void ClosePlugin_DEV9();
|
||||
virtual void ClosePlugin_USB();
|
||||
virtual void ClosePlugin_FW();
|
||||
virtual void ClosePlugin_Mcd();
|
||||
|
||||
friend class SysMtgsThread;
|
||||
};
|
||||
|
|
|
@ -26,7 +26,9 @@ static const u8 cardh[4] = { 0xFF, 0xFF, 0x5a, 0x5d };
|
|||
// Memory Card Specs : Sector size etc.
|
||||
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
|
||||
// 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()
|
||||
{
|
||||
memzero(sio);
|
||||
memzero(m_PostSavestateCards);
|
||||
memzero(m_ForceEjectionTimeout);
|
||||
|
||||
// Transfer(?) Ready and the Buffer is Empty
|
||||
sio.StatReg = TX_RDY | TX_EMPTY;
|
||||
|
@ -602,7 +604,18 @@ void InitializeSIO(u8 value)
|
|||
const uint port = sio.GetMemcardIndex();
|
||||
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;
|
||||
PAD_LOG("START MEMCARD [port:%d, slot:%d] - Present", port, slot );
|
||||
|
@ -654,19 +667,29 @@ void SaveStateBase::sioFreeze()
|
|||
FreezeTag( "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() )
|
||||
{
|
||||
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 )
|
||||
m_mcdCRCs[port][slot] = SysPlugins.McdGetCRC( port, slot );
|
||||
const int slot = 0; // see above comment about multitap slowness
|
||||
m_mcdCRCs[port][slot] = SysPlugins.McdGetCRC( port, slot );
|
||||
}
|
||||
}
|
||||
|
||||
Freeze( m_mcdCRCs );
|
||||
|
||||
if( IsLoading() && EmuConfig.McdEnableEjection )
|
||||
{
|
||||
// Notes:
|
||||
// Notes on the ForceEjectionTimeout:
|
||||
// * TOTA works with values as low as 20 here.
|
||||
// It "times out" with values around 1800 (forces user to check the memcard
|
||||
// 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!)
|
||||
|
||||
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 );
|
||||
if( newCRC != m_mcdCRCs[port][slot] )
|
||||
{
|
||||
u64 newCRC = SysPlugins.McdGetCRC( 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 )
|
||||
{
|
||||
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;
|
||||
|
||||
jNO_DEFAULT
|
||||
|
@ -561,7 +561,7 @@ void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
|
|||
{
|
||||
ApplyDefaults();
|
||||
|
||||
if( DocsFolderMode != DocsFolder_CWD )
|
||||
//if( DocsFolderMode != DocsFolder_CWD )
|
||||
{
|
||||
for( int i=0; i<FolderId_COUNT; ++i )
|
||||
operator[]( (FoldersEnum_t)i ).Normalize();
|
||||
|
@ -719,7 +719,7 @@ void RelocateLogfile()
|
|||
//
|
||||
void AppConfig_OnChangedSettingsFolder( bool overwrite )
|
||||
{
|
||||
if( DocsFolderMode != DocsFolder_CWD )
|
||||
//if( DocsFolderMode != DocsFolder_CWD )
|
||||
PathDefs::GetDocuments().Mkdir();
|
||||
|
||||
GetSettingsFolder().Mkdir();
|
||||
|
|
|
@ -25,7 +25,7 @@ enum DocsModeType
|
|||
DocsFolder_User,
|
||||
|
||||
// uses the current working directory for program data
|
||||
DocsFolder_CWD,
|
||||
//DocsFolder_CWD,
|
||||
|
||||
// uses a custom location for program data
|
||||
DocsFolder_Custom,
|
||||
|
|
|
@ -500,26 +500,29 @@ void SysExecEvent_SaveSinglePlugin::InvokeEvent()
|
|||
s_DisableGsWindow = true; // keeps the GS window smooth by avoiding closing the window
|
||||
|
||||
ScopedCoreThreadPause paused_core;
|
||||
_LoadPluginsImmediate();
|
||||
//_LoadPluginsImmediate();
|
||||
|
||||
ScopedPtr<VmStateBuffer> plugstore;
|
||||
|
||||
if( CoreThread.HasActiveMachine() )
|
||||
if( CorePlugins.AreLoaded() )
|
||||
{
|
||||
Console.WriteLn( Color_Green, L"Suspending single plugin: " + tbl_PluginInfo[m_pid].GetShortname() );
|
||||
memSavingState save( plugstore=new VmStateBuffer(L"StateCopy_SinglePlugin") );
|
||||
GetCorePlugins().Freeze( m_pid, save );
|
||||
}
|
||||
|
||||
GetCorePlugins().Close( m_pid );
|
||||
_post_and_wait( paused_core );
|
||||
ScopedPtr<VmStateBuffer> plugstore;
|
||||
|
||||
if( plugstore )
|
||||
{
|
||||
Console.WriteLn( Color_Green, L"Recovering single plugin: " + tbl_PluginInfo[m_pid].GetShortname() );
|
||||
memLoadingState load( plugstore );
|
||||
GetCorePlugins().Freeze( m_pid, load );
|
||||
GetCorePlugins().Close( m_pid ); // hack for stupid GS plugins.
|
||||
if( CoreThread.HasActiveMachine() )
|
||||
{
|
||||
Console.WriteLn( Color_Green, L"Suspending single plugin: " + tbl_PluginInfo[m_pid].GetShortname() );
|
||||
memSavingState save( plugstore=new VmStateBuffer(L"StateCopy_SinglePlugin") );
|
||||
GetCorePlugins().Freeze( m_pid, save );
|
||||
}
|
||||
|
||||
GetCorePlugins().Close( m_pid );
|
||||
_post_and_wait( paused_core );
|
||||
|
||||
if( plugstore )
|
||||
{
|
||||
Console.WriteLn( Color_Green, L"Recovering single plugin: " + tbl_PluginInfo[m_pid].GetShortname() );
|
||||
memLoadingState load( plugstore );
|
||||
GetCorePlugins().Freeze( m_pid, load );
|
||||
GetCorePlugins().Close( m_pid ); // hack for stupid GS plugins.
|
||||
}
|
||||
}
|
||||
|
||||
s_DisableGsWindow = false;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "System/SysThreads.h"
|
||||
#include "pxEventThread.h"
|
||||
|
||||
#include "AppCommon.h"
|
||||
#include "AppCorePlugins.h"
|
||||
#include "SaveState.h"
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
|
||||
SysExecEvent_SaveSinglePlugin( PluginsEnum_t pid=PluginId_GS )
|
||||
{
|
||||
m_pid = pid;
|
||||
m_pid = pid;
|
||||
}
|
||||
|
||||
SysExecEvent_SaveSinglePlugin& SetPluginId( PluginsEnum_t pid )
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
evt.Skip();
|
||||
if( (evt.GetId() != wxID_OK) && (evt.GetId() != wxID_CANCEL) && (evt.GetId() != wxID_APPLY) )
|
||||
{
|
||||
if( wxWindow* apply = FindWindow( wxID_APPLY ) ) apply->Enable();
|
||||
}
|
||||
SomethingChanged();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ namespace Dialogs
|
|||
void AddListbook( wxSizer* sizer=NULL );
|
||||
void CreateListbook( wxImageList& bookicons );
|
||||
|
||||
virtual void SomethingChanged();
|
||||
|
||||
template< typename T >
|
||||
void AddPage( const char* label, int iconid );
|
||||
|
||||
|
@ -68,8 +70,8 @@ namespace Dialogs
|
|||
void OnCloseWindow( wxCloseEvent& evt );
|
||||
|
||||
void OnSetSettingsPage( wxCommandEvent& evt );
|
||||
void OnSomethingChanged( wxCommandEvent& evt );
|
||||
|
||||
virtual void OnSomethingChanged( wxCommandEvent& evt );
|
||||
virtual wxString& GetConfSettingsTabName() const=0;
|
||||
};
|
||||
|
||||
|
|
|
@ -61,9 +61,9 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint
|
|||
if( m_radio_CardSize ) m_radio_CardSize->Realize();
|
||||
|
||||
wxBoxSizer& s_buttons( *new wxBoxSizer(wxHORIZONTAL) );
|
||||
s_buttons += new wxButton( this, wxID_OK, _("Create") ) | pxProportion(2);
|
||||
s_buttons += new wxButton( this, wxID_OK, _("Create") ) | pxProportion(2);
|
||||
s_buttons += pxStretchSpacer(3);
|
||||
s_buttons += new wxButton( this, wxID_CANCEL ) | pxProportion(2);
|
||||
s_buttons += new wxButton( this, wxID_CANCEL ) | pxProportion(2);
|
||||
|
||||
wxBoxSizer& s_padding( *new wxBoxSizer(wxVERTICAL) );
|
||||
|
||||
|
@ -73,13 +73,14 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint
|
|||
s_padding += m_filepicker | StdExpand();
|
||||
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 += m_radio_CardSize | StdExpand();
|
||||
s_padding += m_radio_CardSize | StdExpand();
|
||||
#ifdef __WXMSW__
|
||||
if( m_check_CompressNTFS ) s_padding += m_check_CompressNTFS | StdExpand();
|
||||
if( m_check_CompressNTFS )
|
||||
s_padding += m_check_CompressNTFS | StdExpand();
|
||||
#endif
|
||||
|
||||
s_padding += 12;
|
||||
|
@ -87,8 +88,6 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint
|
|||
|
||||
*this += s_padding | StdExpand();
|
||||
|
||||
|
||||
//FindItem( wxID_OK )->SetLabel(_("Create"));
|
||||
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnOk_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 )
|
||||
{
|
||||
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
|
||||
) )
|
||||
{
|
||||
|
|
|
@ -172,6 +172,9 @@ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
|
|||
//AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), 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 += StdPadding;
|
||||
*this += new wxStaticLine( this ) | StdExpand();
|
||||
|
|
|
@ -58,6 +58,9 @@ public:
|
|||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
void Open();
|
||||
void Close();
|
||||
|
||||
s32 IsPresent ( uint slot );
|
||||
s32 Read ( uint slot, u8 *dest, 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()
|
||||
{
|
||||
memset8<0xff>( m_effeffs );
|
||||
}
|
||||
|
||||
void FileMemoryCard::Open()
|
||||
{
|
||||
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 ) );
|
||||
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();
|
||||
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 ) )
|
||||
{
|
||||
Msgbox::Alert(
|
||||
|
@ -153,7 +183,7 @@ FileMemoryCard::FileMemoryCard()
|
|||
}
|
||||
|
||||
// [TODO] : Add memcard size detection and report it to the console log.
|
||||
// (8MB, 256Mb, whatever)
|
||||
// (8MB, 256Mb, formatted, unformatted, etc ...)
|
||||
|
||||
#ifdef __WXMSW__
|
||||
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).
|
||||
bool FileMemoryCard::Seek( wxFFile& f, u32 adr )
|
||||
{
|
||||
|
@ -308,6 +344,16 @@ uint FileMcd_ConvertToSlot( uint port, uint slot )
|
|||
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 )
|
||||
{
|
||||
return thisptr->impl.IsPresent( FileMcd_ConvertToSlot( port, slot ) );
|
||||
|
@ -337,6 +383,9 @@ Component_FileMcd::Component_FileMcd()
|
|||
{
|
||||
memzero( api );
|
||||
|
||||
api.Base.EmuOpen = FileMcd_EmuOpen;
|
||||
api.Base.EmuClose = FileMcd_EmuClose;
|
||||
|
||||
api.McdIsPresent = FileMcd_IsPresent;
|
||||
api.McdRead = FileMcd_Read;
|
||||
api.McdSave = FileMcd_Save;
|
||||
|
|
|
@ -69,6 +69,7 @@ void Panels::BaseSelectorPanel::RefreshSelections()
|
|||
|
||||
void Panels::BaseSelectorPanel::OnRefreshSelections( wxCommandEvent& evt )
|
||||
{
|
||||
evt.Skip();
|
||||
RefreshSelections();
|
||||
}
|
||||
|
||||
|
@ -104,7 +105,7 @@ Panels::BiosSelectorPanel::BiosSelectorPanel( wxWindow* parent, int idealWidth )
|
|||
*this += refreshButton | pxBorder(wxLEFT, StdPadding);
|
||||
*this += 8;
|
||||
*this += m_FolderPicker | StdExpand();
|
||||
|
||||
|
||||
Connect( refreshButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BiosSelectorPanel::OnRefreshSelections) );
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "AppCoreThread.h"
|
||||
#include "System.h"
|
||||
|
||||
#include "ConfigurationPanels.h"
|
||||
#include "MemoryCardPanels.h"
|
||||
#include "System.h"
|
||||
|
||||
#include <wx/filepicker.h>
|
||||
#include <wx/ffile.h>
|
||||
|
@ -490,7 +492,10 @@ void Panels::MemoryCardListPanel_Simple::UpdateUI()
|
|||
void Panels::MemoryCardListPanel_Simple::Apply()
|
||||
{
|
||||
//_parent::Apply();
|
||||
|
||||
|
||||
ScopedCoreThreadClose closed_core;
|
||||
closed_core.AllowResume();
|
||||
|
||||
for( uint slot=0; slot<8; ++slot )
|
||||
{
|
||||
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)
|
||||
{
|
||||
evt.Skip();
|
||||
|
||||
const int sel = m_listview->GetFirstSelected();
|
||||
if( wxNOT_FOUND == sel ) return;
|
||||
const uint slot = sel;
|
||||
|
|
|
@ -51,12 +51,6 @@ Panels::DocsFolderPickerPanel::DocsFolderPickerPanel( wxWindow* parent, bool isF
|
|||
_("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(
|
||||
_("Custom folder:"),
|
||||
wxEmptyString,
|
||||
|
|
|
@ -672,7 +672,7 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
|
|||
else if( m_ComponentBoxes->Get(pid).GetSelection() == wxNOT_FOUND )
|
||||
{
|
||||
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 );
|
||||
|
||||
|
|
Loading…
Reference in New Issue