Handle filter management in the folder memcard class rather than outside.

This prevents desync between what is assumed to be the active filter and
what is actually the active filter, fixing errors like #1179 where the
memory cards are closed and reopened for whatever reason.
This commit is contained in:
Admiral H. Curtiss 2016-04-02 03:44:11 +02:00
parent 3b7ba39590
commit 97a68becb9
8 changed files with 66 additions and 29 deletions

View File

@ -1109,7 +1109,7 @@ typedef struct _PS2E_ComponentAPI_Mcd
// Used by the FolderMemoryCard to find a good time to flush written data to the host file system.
void (PS2E_CALLBACK* McdNextFrame)( PS2E_THISPTR thisptr, uint port, uint slot );
void (PS2E_CALLBACK* McdReIndex)( PS2E_THISPTR thisptr, uint port, uint slot, const wxString& filter );
bool (PS2E_CALLBACK* McdReIndex)( PS2E_THISPTR thisptr, uint port, uint slot, const wxString& filter );
void* reserved[6];

View File

@ -70,8 +70,8 @@ void SysPluginBindings::McdNextFrame( uint port, uint slot ) {
Mcd->McdNextFrame( (PS2E_THISPTR) Mcd, port, slot );
}
void SysPluginBindings::McdReIndex( uint port, uint slot, const wxString& filter ) {
Mcd->McdReIndex( (PS2E_THISPTR) Mcd, port, slot, filter );
bool SysPluginBindings::McdReIndex( uint port, uint slot, const wxString& filter ) {
return Mcd->McdReIndex( (PS2E_THISPTR) Mcd, port, slot, filter );
}
// ----------------------------------------------------------------------------

View File

@ -242,7 +242,7 @@ public:
void McdEraseBlock( uint port, uint slot, u32 adr );
u64 McdGetCRC( uint port, uint slot );
void McdNextFrame( uint port, uint slot );
void McdReIndex( uint port, uint slot, const wxString& filter );
bool McdReIndex( uint port, uint slot, const wxString& filter );
friend class SysCorePlugins;
};

View File

@ -53,18 +53,30 @@ wxString GetTimeMsStr(){
}
//allow timeout also for the mcd manager panel
void SetForceMcdEjectTimeoutNow( uint port, uint slot )
{
mcds[port][slot].ForceEjection_Timeout = FORCED_MCD_EJECTION_MAX_TRIES;
}
void SetForceMcdEjectTimeoutNow()
{
for( u8 port=0; port<2; ++port )
for( u8 slot=0; slot<4; ++slot )
mcds[port][slot].ForceEjection_Timeout = FORCED_MCD_EJECTION_MAX_TRIES;
for ( uint port = 0; port < 2; ++port ) {
for ( uint slot = 0; slot < 4; ++slot ) {
SetForceMcdEjectTimeoutNow( port, slot );
}
}
}
void ClearMcdEjectTimeoutNow( uint port, uint slot )
{
mcds[port][slot].ForceEjection_Timeout = 0;
}
void ClearMcdEjectTimeoutNow()
{
for( u8 port=0; port<2; ++port )
for( u8 slot=0; slot<4; ++slot )
mcds[port][slot].ForceEjection_Timeout = 0;
for ( uint port = 0; port < 2; ++port ) {
for ( uint slot = 0; slot < 4; ++slot ) {
ClearMcdEjectTimeoutNow( port, slot );
}
}
}
// SIO Inline'd IRQs : Calls the SIO interrupt handlers directly instead of
@ -886,18 +898,14 @@ void sioNextFrame() {
}
}
// Used to figure out when a new game boots, so that memory cards can re-index themselves and only load data relevant to that game.
wxString SioCurrentGameSerial = L"";
void sioSetGameSerial( const wxString& serial ) {
if ( serial == SioCurrentGameSerial ) { return; }
SioCurrentGameSerial = serial;
for ( uint port = 0; port < 2; ++port ) {
for ( uint slot = 0; slot < 4; ++slot ) {
mcds[port][slot].ReIndex( serial );
if ( mcds[port][slot].ReIndex( serial ) ) {
SetForceMcdEjectTimeoutNow( port, slot );
}
}
}
SetForceMcdEjectTimeoutNow();
}
void SaveStateBase::sioFreeze()

View File

@ -87,8 +87,8 @@ struct _mcd
SysPlugins.McdNextFrame( port, slot );
}
void ReIndex(const wxString& filter = L"") {
SysPlugins.McdReIndex( port, slot, filter );
bool ReIndex(const wxString& filter = L"") {
return SysPlugins.McdReIndex( port, slot, filter );
}
};

View File

@ -562,17 +562,17 @@ static void PS2E_CALLBACK FileMcd_NextFrame( PS2E_THISPTR thisptr, uint port, ui
}
}
static void PS2E_CALLBACK FileMcd_ReIndex( PS2E_THISPTR thisptr, uint port, uint slot, const wxString& filter ) {
static bool PS2E_CALLBACK FileMcd_ReIndex( PS2E_THISPTR thisptr, uint port, uint slot, const wxString& filter ) {
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
switch ( g_Conf->Mcd[combinedSlot].Type ) {
//case MemoryCardType::MemoryCard_File:
// thisptr->impl.ReIndex( combinedSlot, filter );
// return thisptr->impl.ReIndex( combinedSlot, filter );
// break;
case MemoryCardType::MemoryCard_Folder:
thisptr->implFolder.ReIndex( combinedSlot, g_Conf->EmuOptions.McdFolderAutoManage, filter );
return thisptr->implFolder.ReIndex( combinedSlot, g_Conf->EmuOptions.McdFolderAutoManage, filter );
break;
default:
return;
return false;
}
}

View File

@ -32,6 +32,8 @@ FolderMemoryCard::FolderMemoryCard() {
m_performFileWrites = false;
m_framesUntilFlush = 0;
m_timeLastWritten = 0;
m_filteringEnabled = false;
m_filteringString = L"";
}
void FolderMemoryCard::InitializeInternalData() {
@ -48,6 +50,8 @@ void FolderMemoryCard::InitializeInternalData() {
m_isEnabled = false;
m_framesUntilFlush = 0;
m_performFileWrites = true;
m_filteringEnabled = false;
m_filteringString = L"";
}
bool FolderMemoryCard::IsFormatted() const {
@ -94,6 +98,8 @@ void FolderMemoryCard::Open( const wxString& fullPath, const AppConfig::McdOptio
if ( disabled ) return;
m_isEnabled = true;
m_filteringEnabled = enableFiltering;
m_filteringString = filter;
LoadMemoryCardData( sizeInClusters, enableFiltering, filter );
SetTimeLastWrittenToNow();
@ -113,6 +119,18 @@ void FolderMemoryCard::Close( bool flush ) {
m_fileMetadataQuickAccess.clear();
}
bool FolderMemoryCard::ReIndex( bool enableFiltering, const wxString& filter ) {
if ( !m_isEnabled ) { return false; }
if ( m_filteringEnabled != enableFiltering || m_filteringString != filter ) {
Close();
Open( enableFiltering, filter );
return true;
}
return false;
}
void FolderMemoryCard::LoadMemoryCardData( const u32 sizeInClusters, const bool enableFiltering, const wxString& filter ) {
bool formatted = false;
@ -1648,11 +1666,13 @@ void FolderMemoryCardAggregator::NextFrame( uint slot ) {
m_cards[slot].NextFrame();
}
void FolderMemoryCardAggregator::ReIndex( uint slot, const bool enableFiltering, const wxString& filter ) {
m_cards[slot].Close();
m_cards[slot].Open( enableFiltering, filter );
bool FolderMemoryCardAggregator::ReIndex( uint slot, const bool enableFiltering, const wxString& filter ) {
if ( m_cards[slot].ReIndex( enableFiltering, filter ) ) {
SetFiltering( enableFiltering );
m_lastKnownFilter = filter;
return true;
}
SetFiltering( enableFiltering );
m_lastKnownFilter = filter;
return false;
}

View File

@ -327,6 +327,10 @@ protected:
// if set to false, nothing is actually written to the file system while flushing, and data is discarded instead
bool m_performFileWrites;
// currently active filter settings
bool m_filteringEnabled;
wxString m_filteringString;
public:
FolderMemoryCard();
virtual ~FolderMemoryCard() throw() {}
@ -341,6 +345,11 @@ public:
// Close the memory card and flush changes to the file system. Set flush to false to not store changes.
void Close( bool flush = true );
// Closes and reopens card with given filter options if they differ from the current ones (returns true),
// or does nothing if they match already (returns false).
// Does nothing and returns false when called on a closed memory card.
bool ReIndex( bool enableFiltering, const wxString& filter );
s32 IsPresent() const;
void GetSizeInfo( PS2E_McdSizeInfo& outways ) const;
bool IsPSX() const;
@ -562,5 +571,5 @@ public:
s32 EraseBlock( uint slot, u32 adr );
u64 GetCRC( uint slot );
void NextFrame( uint slot );
void ReIndex( uint slot, const bool enableFiltering, const wxString& filter );
bool ReIndex( uint slot, const bool enableFiltering, const wxString& filter );
};