From c0cc91fd0a9a780ddd2c70e83263e3cfcb65a56e Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 30 Jun 2015 03:33:32 +0200 Subject: [PATCH] FolderMemoryCard: Only add folders if all files and subfolders in it also fit into the remaining memory card space. This avoids situations where, for example, it would only add the icon file but not the game data file because the memory card was near-full. --- pcsx2/gui/MemoryCardFolder.cpp | 35 +++++++++++++++++++++++++++++++++- pcsx2/gui/MemoryCardFolder.h | 3 +++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pcsx2/gui/MemoryCardFolder.cpp b/pcsx2/gui/MemoryCardFolder.cpp index 7c13ed8a9d..a4fcb7f795 100644 --- a/pcsx2/gui/MemoryCardFolder.cpp +++ b/pcsx2/gui/MemoryCardFolder.cpp @@ -316,7 +316,7 @@ bool FolderMemoryCard::AddFolder( MemoryCardFileEntry* const dirEntry, const wxS } // make sure we have enough space on the memcard for the directory - const u32 newNeededClusters = ( dirEntry->entry.data.length % 2 ) == 0 ? 2 : 1; + const u32 newNeededClusters = CalculateRequiredClustersOfDirectory( dirPath + L"/" + fileName ) + ( ( dirEntry->entry.data.length % 2 ) == 0 ? 1 : 0 ); if ( newNeededClusters > GetAmountFreeDataClusters() ) { Console.Warning( GetCardFullMessage( fileName ) ); hasNext = dir.GetNext( &fileName ); @@ -454,6 +454,39 @@ bool FolderMemoryCard::AddFile( MemoryCardFileEntry* const dirEntry, const wxStr return true; } +u32 FolderMemoryCard::CalculateRequiredClustersOfDirectory( const wxString& dirPath ) { + const u32 clusterSize = m_superBlock.data.pages_per_cluster * m_superBlock.data.page_len; + u32 requiredFileEntryPages = 2; + u32 requiredClusters = 0; + + wxDir dir( dirPath ); + wxString fileName; + bool hasNext = dir.GetFirst( &fileName ); + while ( hasNext ) { + if ( fileName.StartsWith( L"_pcsx2_" ) ) { + hasNext = dir.GetNext( &fileName ); + continue; + } + + ++requiredFileEntryPages; + wxFileName file( dirPath, fileName ); + wxString path = file.GetFullPath(); + bool isFile = wxFile::Exists( path ); + + if ( isFile ) { + const u32 filesize = file.GetSize().GetValue(); + const u32 countClusters = ( filesize % clusterSize ) != 0 ? ( filesize / clusterSize + 1 ) : ( filesize / clusterSize ); + requiredClusters += countClusters; + } else { + requiredClusters += CalculateRequiredClustersOfDirectory( path ); + } + + hasNext = dir.GetNext( &fileName ); + } + + return requiredClusters + requiredFileEntryPages / 2 + ( requiredFileEntryPages % 2 == 0 ? 0 : 1 ); +} + MemoryCardFileMetadataReference* FolderMemoryCard::AddDirEntryToMetadataQuickAccess( MemoryCardFileEntry* const entry, MemoryCardFileMetadataReference* const parent ) { MemoryCardFileMetadataReference* ref = &m_fileMetadataQuickAccess[entry->entry.data.cluster]; ref->parent = parent; diff --git a/pcsx2/gui/MemoryCardFolder.h b/pcsx2/gui/MemoryCardFolder.h index e30d20f9d9..5544143805 100644 --- a/pcsx2/gui/MemoryCardFolder.h +++ b/pcsx2/gui/MemoryCardFolder.h @@ -357,6 +357,9 @@ protected: // - parent: pointer to the parent dir's quick-access reference element bool AddFile( MemoryCardFileEntry* const dirEntry, const wxString& dirPath, const wxString& fileName, MemoryCardFileMetadataReference* parent = nullptr ); + // calculates the amount of clusters a directory would use up if put into a memory card + u32 CalculateRequiredClustersOfDirectory( const wxString& dirPath ); + // adds a file to the quick-access dictionary, so it can be accessed more efficiently (ie, without searching through the entire file system) later void AddFileEntryToMetadataQuickAccess( MemoryCardFileEntry* const entry, MemoryCardFileMetadataReference* const parent );