From 03a6be28c056c7b3e6fb977bde07ed45e4b92f06 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 4 Jul 2015 01:42:17 +0200 Subject: [PATCH] FolderMemoryCard: Write the SuperBlock as part of Flush() instead of when the card is Close()d. This mainly means that the superblock is now no longer written every single time the memory card is closed, but only when it's changed (which should be exactly once, when the memory card is formatted). It also means that you can format a memory card and then have the emulator crash later without having to reformat the card next time. --- pcsx2/gui/MemoryCardFolder.cpp | 53 ++++++++++++++++++++++------------ pcsx2/gui/MemoryCardFolder.h | 9 ++++-- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/pcsx2/gui/MemoryCardFolder.cpp b/pcsx2/gui/MemoryCardFolder.cpp index 3b64cc0ace..aad098d9ca 100644 --- a/pcsx2/gui/MemoryCardFolder.cpp +++ b/pcsx2/gui/MemoryCardFolder.cpp @@ -99,12 +99,6 @@ void FolderMemoryCard::Close() { Flush(); - wxFileName superBlockFileName( m_folderName.GetPath(), L"_pcsx2_superblock" ); - wxFFile superBlockFile( superBlockFileName.GetFullPath().c_str(), L"wb" ); - if ( superBlockFile.IsOpened() ) { - superBlockFile.Write( &m_superBlock.raw, sizeof( m_superBlock.raw ) ); - } - m_cache.clear(); m_fileMetadataQuickAccess.clear(); m_lastAccessedFile.Close(); @@ -828,7 +822,7 @@ void FolderMemoryCard::Flush() { } // first write the superblock if necessary - FlushBlock( 0 ); + FlushSuperBlock(); if ( !IsFormatted() ) { return; } // check if we were interrupted in the middle of a save operation, if yes abort @@ -877,24 +871,40 @@ void FolderMemoryCard::Flush() { Console.WriteLn( L"(FolderMcd) Done! Took %u ms.", timeFlushEnd - timeFlushStart ); } -void FolderMemoryCard::FlushPage( const u32 page ) { +bool FolderMemoryCard::FlushPage( const u32 page ) { auto it = m_cache.find( page ); if ( it != m_cache.end() ) { WriteWithoutCache( &it->second.raw[0], page * PageSizeRaw, PageSize ); m_cache.erase( it ); + return true; } + return false; } -void FolderMemoryCard::FlushCluster( const u32 cluster ) { +bool FolderMemoryCard::FlushCluster( const u32 cluster ) { const u32 page = cluster * 2; - FlushPage( page ); - FlushPage( page + 1 ); + bool flushed = false; + if ( FlushPage( page ) ) { flushed = true; } + if ( FlushPage( page + 1 ) ) { flushed = true; } + return flushed; } -void FolderMemoryCard::FlushBlock( const u32 block ) { +bool FolderMemoryCard::FlushBlock( const u32 block ) { const u32 page = block * 16; + bool flushed = false; for ( int i = 0; i < 16; ++i ) { - FlushPage( page + i ); + if ( FlushPage( page + i ) ) { flushed = true; } + } + return flushed; +} + +void FolderMemoryCard::FlushSuperBlock() { + if ( FlushBlock( 0 ) ) { + wxFileName superBlockFileName( m_folderName.GetPath(), L"_pcsx2_superblock" ); + wxFFile superBlockFile( superBlockFileName.GetFullPath().c_str(), L"wb" ); + if ( superBlockFile.IsOpened() ) { + superBlockFile.Write( &m_superBlock.raw, sizeof( m_superBlock.raw ) ); + } } } @@ -1169,15 +1179,22 @@ u32 FolderMemoryCard::GetSizeInClusters() const { } void FolderMemoryCard::SetSizeInClusters( u32 clusters ) { - m_superBlock.data.clusters_per_card = clusters; + superBlockUnion newSuperBlock; + memcpy( &newSuperBlock.raw[0], &m_superBlock.raw[0], sizeof( newSuperBlock.raw ) ); + + newSuperBlock.data.clusters_per_card = clusters; const u32 alloc_offset = clusters / 0x100 + 9; - m_superBlock.data.alloc_offset = alloc_offset; - m_superBlock.data.alloc_end = clusters - 0x10 - alloc_offset; + newSuperBlock.data.alloc_offset = alloc_offset; + newSuperBlock.data.alloc_end = clusters - 0x10 - alloc_offset; const u32 blocks = clusters / 8; - m_superBlock.data.backup_block1 = blocks - 1; - m_superBlock.data.backup_block2 = blocks - 2; + newSuperBlock.data.backup_block1 = blocks - 1; + newSuperBlock.data.backup_block2 = blocks - 2; + + for ( size_t i = 0; i < sizeof( newSuperBlock.raw ) / PageSize; ++i ) { + Save( &newSuperBlock.raw[i * PageSize], i * PageSizeRaw, PageSize ); + } } void FolderMemoryCard::SetSizeInMB( u32 megaBytes ) { diff --git a/pcsx2/gui/MemoryCardFolder.h b/pcsx2/gui/MemoryCardFolder.h index cfa3b73259..ae1109e6b1 100644 --- a/pcsx2/gui/MemoryCardFolder.h +++ b/pcsx2/gui/MemoryCardFolder.h @@ -416,13 +416,16 @@ protected: void Flush(); // flush a single page of the cache to the internal data and/or host file system - void FlushPage( const u32 page ); + bool FlushPage( const u32 page ); // flush a memory card cluster of the cache to the internal data and/or host file system - void FlushCluster( const u32 cluster ); + bool FlushCluster( const u32 cluster ); // flush a whole memory card block of the cache to the internal data and/or host file system - void FlushBlock( const u32 block ); + bool FlushBlock( const u32 block ); + + // flush the superblock to the internal data and/or host file system + void FlushSuperBlock(); // flush all directory and file entries to the internal data void FlushFileEntries();