FolderMemoryCard: Some code cleanup.

This commit is contained in:
Admiral H. Curtiss 2015-05-30 00:42:05 +02:00
parent f40b679653
commit 8029412fb7
3 changed files with 86 additions and 79 deletions

View File

@ -75,8 +75,6 @@ public:
s32 EraseBlock ( uint slot, u32 adr );
u64 GetCRC ( uint slot );
void NextFrame( uint slot );
protected:
bool Seek( wxFFile& f, u32 adr );
bool Create( const wxString& mcdFile, uint sizeInMB );
@ -408,11 +406,6 @@ u64 FileMemoryCard::GetCRC( uint slot )
return retval;
}
void FileMemoryCard::NextFrame( uint slot )
{
}
// --------------------------------------------------------------------------------------
// MemoryCard Component API Bindings
// --------------------------------------------------------------------------------------
@ -542,9 +535,9 @@ static u64 PS2E_CALLBACK FileMcd_GetCRC( PS2E_THISPTR thisptr, uint port, uint s
static void PS2E_CALLBACK FileMcd_NextFrame( PS2E_THISPTR thisptr, uint port, uint slot ) {
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
switch ( g_Conf->Mcd[combinedSlot].Type ) {
case MemoryCardType::MemoryCard_File:
thisptr->impl.NextFrame( combinedSlot );
break;
//case MemoryCardType::MemoryCard_File:
// thisptr->impl.NextFrame( combinedSlot );
// break;
case MemoryCardType::MemoryCard_Folder:
thisptr->implFolder.NextFrame( combinedSlot );
break;

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
* Copyright (C) 2002-2015 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -47,14 +47,18 @@ bool FolderMemoryCard::IsFormatted() {
}
void FolderMemoryCard::Open( const bool enableFiltering, const wxString& filter ) {
Open( g_Conf->FullpathToMcd( m_slot ), g_Conf->Mcd[m_slot], enableFiltering, filter );
}
void FolderMemoryCard::Open( const wxString& fullPath, const AppConfig::McdOptions& mcdOptions, const bool enableFiltering, const wxString& filter ) {
InitializeInternalData();
wxFileName configuredFileName( g_Conf->FullpathToMcd( m_slot ) );
folderName = wxFileName( configuredFileName.GetFullPath() + L"/" );
wxFileName configuredFileName( fullPath );
m_folderName = wxFileName( configuredFileName.GetFullPath() + L"/" );
wxString str( configuredFileName.GetFullPath() );
bool disabled = false;
if ( g_Conf->Mcd[m_slot].Enabled && g_Conf->Mcd[m_slot].Type == MemoryCardType::MemoryCard_Folder ) {
if ( mcdOptions.Enabled && mcdOptions.Type == MemoryCardType::MemoryCard_Folder ) {
if ( configuredFileName.GetFullName().IsEmpty() ) {
str = L"[empty filename]";
disabled = true;
@ -65,8 +69,8 @@ void FolderMemoryCard::Open( const bool enableFiltering, const wxString& filter
}
// if nothing exists at a valid location, create a directory for the memory card
if ( !disabled && !folderName.DirExists() ) {
if ( !folderName.Mkdir() ) {
if ( !disabled && !m_folderName.DirExists() ) {
if ( !m_folderName.Mkdir() ) {
str = L"[couldn't create folder]";
disabled = true;
}
@ -91,7 +95,7 @@ void FolderMemoryCard::Close() {
Flush();
wxFileName superBlockFileName( folderName.GetPath(), L"_pcsx2_superblock" );
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 ) );
@ -102,7 +106,7 @@ void FolderMemoryCard::LoadMemoryCardData( const bool enableFiltering, const wxS
bool formatted = false;
// read superblock if it exists
wxFileName superBlockFileName( folderName.GetPath(), L"_pcsx2_superblock" );
wxFileName superBlockFileName( m_folderName.GetPath(), L"_pcsx2_superblock" );
if ( superBlockFileName.FileExists() ) {
wxFFile superBlockFile( superBlockFileName.GetFullPath().c_str(), L"rb" );
if ( superBlockFile.IsOpened() && superBlockFile.Read( &m_superBlock.raw, sizeof( m_superBlock.raw ) ) >= sizeof( m_superBlock.data ) ) {
@ -121,7 +125,7 @@ void FolderMemoryCard::LoadMemoryCardData( const bool enableFiltering, const wxS
CreateFat();
CreateRootDir();
MemoryCardFileEntry* const rootDirEntry = &m_fileEntryDict[m_superBlock.data.rootdir_cluster].entries[0];
AddFolder( rootDirEntry, folderName.GetPath(), enableFiltering, filter );
AddFolder( rootDirEntry, m_folderName.GetPath(), enableFiltering, filter );
}
}
@ -224,29 +228,6 @@ u32 FolderMemoryCard::GetLastClusterOfData( const u32 cluster ) {
return entryCluster;
}
u64 FolderMemoryCard::ConvertToMemoryCardTimestamp( const wxDateTime& time ) {
if ( !time.IsValid() ) {
return 0;
}
union {
MemoryCardFileEntryDateTime data;
u64 value;
} t;
wxDateTime::Tm tm = time.GetTm( wxDateTime::GMT9 );
t.data.unused = 0;
t.data.second = tm.sec;
t.data.minute = tm.min;
t.data.hour = tm.hour;
t.data.day = tm.mday;
t.data.month = tm.mon + 1;
t.data.year = tm.year;
return t.value;
}
MemoryCardFileEntry* FolderMemoryCard::AppendFileEntryToDir( MemoryCardFileEntry* const dirEntry ) {
u32 entryCluster = GetLastClusterOfData( dirEntry->entry.data.cluster );
@ -358,8 +339,8 @@ bool FolderMemoryCard::AddFolder( MemoryCardFileEntry* const dirEntry, const wxS
metaFile.Close();
} else {
newDirEntry->entry.data.mode = MemoryCardFileEntry::DefaultDirMode;
newDirEntry->entry.data.timeCreated.value = ConvertToMemoryCardTimestamp( creationTime );
newDirEntry->entry.data.timeModified.value = ConvertToMemoryCardTimestamp( modificationTime );
newDirEntry->entry.data.timeCreated = MemoryCardFileEntryDateTime::FromWxDateTime( creationTime );
newDirEntry->entry.data.timeModified = MemoryCardFileEntryDateTime::FromWxDateTime( modificationTime );
}
newDirEntry->entry.data.length = 2;
@ -398,7 +379,7 @@ bool FolderMemoryCard::AddFolder( MemoryCardFileEntry* const dirEntry, const wxS
bool FolderMemoryCard::AddFile( MemoryCardFileEntry* const dirEntry, const wxString& dirPath, const wxString& fileName ) {
wxFileName relativeFilePath( dirPath, fileName );
relativeFilePath.MakeRelativeTo( folderName.GetPath() );
relativeFilePath.MakeRelativeTo( m_folderName.GetPath() );
Console.WriteLn( L"(FolderMcd) Adding file: %s", WX_STR( relativeFilePath.GetFullPath() ) );
wxFileName fileInfo( dirPath, fileName );
@ -430,8 +411,8 @@ bool FolderMemoryCard::AddFile( MemoryCardFileEntry* const dirEntry, const wxStr
metaFile.Close();
} else {
newFileEntry->entry.data.mode = MemoryCardFileEntry::DefaultFileMode;
newFileEntry->entry.data.timeCreated.value = ConvertToMemoryCardTimestamp( creationTime );
newFileEntry->entry.data.timeModified.value = ConvertToMemoryCardTimestamp( modificationTime );
newFileEntry->entry.data.timeCreated = MemoryCardFileEntryDateTime::FromWxDateTime( creationTime );
newFileEntry->entry.data.timeModified = MemoryCardFileEntryDateTime::FromWxDateTime( modificationTime );
}
newFileEntry->entry.data.length = filesize;
@ -601,7 +582,7 @@ bool FolderMemoryCard::ReadFromFile( u8 *dest, u32 adr, u32 dataLength ) {
const u32 fatCluster = cluster - m_superBlock.data.alloc_offset;
// figure out which file to read from
wxFileName fileName( folderName );
wxFileName fileName( m_folderName );
u32 clusterNumber;
const MemoryCardFileEntry* const entry = GetFileEntryFromFileDataCluster( m_superBlock.data.rootdir_cluster, fatCluster, &fileName, fileName.GetDirCount(), &clusterNumber );
if ( entry != nullptr ) {
@ -768,6 +749,7 @@ void FolderMemoryCard::Flush() {
const u32 rootDirCluster = m_superBlock.data.rootdir_cluster;
const u32 rootDirPage = ( rootDirCluster + m_superBlock.data.alloc_offset ) * 2;
Flush( rootDirPage );
Flush( rootDirPage + 1 );
MemoryCardFileEntryCluster* rootEntries = &m_fileEntryDict[rootDirCluster];
if ( rootEntries->entries[0].IsValid() && rootEntries->entries[0].IsUsed() ) {
FlushFileEntries( rootDirCluster, rootEntries->entries[0].entry.data.length );
@ -807,7 +789,7 @@ void FolderMemoryCard::FlushFileEntries( const u32 dirCluster, const u32 remaini
const wxString subDirPath = dirPath + L"/" + subDirName;
// if this directory has nonstandard metadata, write that to the file system
wxFileName metaFileName( folderName.GetFullPath() + subDirPath + L"/_pcsx2_meta_directory" );
wxFileName metaFileName( m_folderName.GetFullPath() + subDirPath + L"/_pcsx2_meta_directory" );
if ( entry->entry.data.mode != MemoryCardFileEntry::DefaultDirMode || entry->entry.data.attr != 0 ) {
if ( !metaFileName.DirExists() ) {
metaFileName.Mkdir();
@ -879,7 +861,7 @@ bool FolderMemoryCard::WriteToFile( const u8* src, u32 adr, u32 dataLength ) {
const u32 fatCluster = cluster - m_superBlock.data.alloc_offset;
// figure out which file to write to
wxFileName fileName( folderName );
wxFileName fileName( m_folderName );
u32 clusterNumber;
const MemoryCardFileEntry* const entry = GetFileEntryFromFileDataCluster( m_superBlock.data.rootdir_cluster, fatCluster, &fileName, fileName.GetDirCount(), &clusterNumber );
if ( entry != nullptr ) {
@ -1024,19 +1006,19 @@ void FolderMemoryCard::CalculateECC( u8* ecc, const u8* data ) {
}
FolderMemoryCardAggregator::FolderMemoryCardAggregator() {
for ( uint i = 0; i < totalCardSlots; ++i ) {
for ( uint i = 0; i < TotalCardSlots; ++i ) {
m_cards[i].SetSlot( i );
}
}
void FolderMemoryCardAggregator::Open() {
for ( int i = 0; i < totalCardSlots; ++i ) {
for ( int i = 0; i < TotalCardSlots; ++i ) {
m_cards[i].Open( m_enableFiltering, m_lastKnownFilter );
}
}
void FolderMemoryCardAggregator::Close() {
for ( int i = 0; i < totalCardSlots; ++i ) {
for ( int i = 0; i < TotalCardSlots; ++i ) {
m_cards[i].Close();
}
}

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 PCSX2 Dev Team
* Copyright (C) 2002-2015 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -17,11 +17,11 @@
#include <wx/file.h>
#include <wx/dir.h>
#include <wx/stopwatch.h>
#include <wx/ffile.h>
#include <map>
#include "PluginCallbacks.h"
#include "AppConfig.h"
// --------------------------------------------------------------------------------------
// Superblock Header Struct
@ -57,6 +57,32 @@ struct MemoryCardFileEntryDateTime {
u8 day;
u8 month;
u16 year;
static MemoryCardFileEntryDateTime FromWxDateTime( const wxDateTime& time ) {
MemoryCardFileEntryDateTime t;
if ( time.IsValid() ) {
wxDateTime::Tm tm = time.GetTm( wxDateTime::GMT9 );
t.unused = 0;
t.second = tm.sec;
t.minute = tm.min;
t.hour = tm.hour;
t.day = tm.mday;
t.month = tm.mon + 1;
t.year = tm.year;
} else {
t.unused = 0;
t.second = 0;
t.minute = 0;
t.hour = 0;
t.day = 0;
t.month = 0;
t.year = 0;
}
return t;
}
};
#pragma pack(pop)
@ -70,18 +96,10 @@ struct MemoryCardFileEntry {
struct MemoryCardFileEntryData {
u32 mode;
u32 length; // number of bytes for file, number of files for dir
union {
MemoryCardFileEntryDateTime data;
u64 value;
u8 raw[8];
} timeCreated;
MemoryCardFileEntryDateTime timeCreated;
u32 cluster; // cluster the start of referred file or folder can be found in
u32 dirEntry; // parent directory entry number, only used if "." entry of subdir
union {
MemoryCardFileEntryDateTime data;
u64 value;
u8 raw[8];
} timeModified;
MemoryCardFileEntryDateTime timeModified;
u32 attr;
u8 padding[0x1C];
u8 name[0x20];
@ -118,9 +136,7 @@ struct MemoryCardPage {
// --------------------------------------------------------------------------------------
// Fakes a memory card using a regular folder/file structure in the host file system
class FolderMemoryCard {
protected:
wxFileName folderName;
public:
// a few constants so we could in theory change the memory card size without too much effort
static const int IndirectFatClusterCount = 1; // should be 32 but only 1 is ever used
static const int PageSize = MemoryCardPage::PageSize;
@ -133,9 +149,11 @@ protected:
static const int TotalPages = 0x4000;
static const int TotalClusters = TotalPages / 2;
static const int TotalBlocks = TotalClusters / 8;
static const int TotalSizeRaw = TotalPages * PageSizeRaw;
static const int FramesAfterWriteUntilFlush = 60;
protected:
union superBlockUnion {
superblock data;
u8 raw[BlockSize];
@ -151,15 +169,24 @@ protected:
u8 m_backupBlock1[BlockSize];
u8 m_backupBlock2[BlockSize];
// stores directory and file metadata
std::map<u32, MemoryCardFileEntryCluster> m_fileEntryDict;
// holds a copy of modified areas of the memory card, in page-sized chunks
// holds a copy of modified pages of the memory card before they're flushed to the file system
std::map<u32, MemoryCardPage> m_cache;
uint m_slot;
bool m_isEnabled;
u64 m_timeLastWritten;
// if > 0, the amount of frames until data is flushed to the file system
// reset to FramesAfterWriteUntilFlush on each write
int m_framesUntilFlush;
// used to figure out if contents were changed for savestate-related purposes, see GetCRC()
u64 m_timeLastWritten;
// path to the folder that contains the files of this memory card
wxFileName m_folderName;
// PS2 memory card slot this card is inserted into
uint m_slot;
bool m_isEnabled;
public:
FolderMemoryCard();
@ -168,7 +195,10 @@ public:
void Lock();
void Unlock();
// Initialize & Load Memory Card with values configured in the Memory Card Manager
void Open( const bool enableFiltering, const wxString& filter );
// Initialize & Load Memory Card with provided custom values
void Open( const wxString& fullPath, const AppConfig::McdOptions& mcdOptions, const bool enableFiltering, const wxString& filter );
void Close();
s32 IsPresent();
@ -219,8 +249,8 @@ protected:
// loads files and folders from the host file system if a superblock exists in the root directory
// if enableFiltering is set to true, only folders whose name contain the filter string are loaded
// filter string can include multiple filters by separating them with "/"
// - enableFiltering: if set to true, only folders whose name contain the filter string are loaded
// - filter: can include multiple filters by separating them with "/"
void LoadMemoryCardData( const bool enableFiltering, const wxString& filter );
// creates the FAT and indirect FAT
@ -244,8 +274,6 @@ protected:
// returns the final cluster of the file or directory which is (partially) stored in the given cluster
u32 GetLastClusterOfData( const u32 cluster );
u64 ConvertToMemoryCardTimestamp( const wxDateTime& time );
// creates and returns a new file entry in the given directory entry, ready to be filled
// returns nullptr when the memory card is full
@ -282,6 +310,7 @@ protected:
void SetTimeLastWrittenToNow();
wxString GetDisabledMessage( uint slot ) const {
return wxsFormat( pxE( L"The PS2-slot %d has been automatically disabled. You can correct the problem\nand re-enable it at any time using Config:Memory cards from the main menu."
), slot//TODO: translate internal slot index to human-readable slot description
@ -298,8 +327,11 @@ protected:
// Forwards the API's requests for specific memory card slots to the correct FolderMemoryCard.
class FolderMemoryCardAggregator {
protected:
static const int totalCardSlots = 8;
FolderMemoryCard m_cards[totalCardSlots];
static const int TotalCardSlots = 8;
FolderMemoryCard m_cards[TotalCardSlots];
// stores the specifics of the current filtering settings, so they can be
// re-applied automatically when memory cards are reloaded
bool m_enableFiltering = true;
wxString m_lastKnownFilter = L"";