mirror of https://github.com/PCSX2/pcsx2.git
MemoryCard: Add support for folder memcards in GUI and make both implementation function side-by-side.
This commit is contained in:
parent
1d46800888
commit
f15c07653c
|
@ -431,10 +431,8 @@ static __fi void VSyncEnd(u32 sCycle)
|
|||
psxVBlankEnd(); // psxCounters vBlank End
|
||||
if (gates) rcntEndGate(true, sCycle); // Counters End Gate Code
|
||||
|
||||
#ifdef MEMORYCARD_USE_FOLDER
|
||||
// FolderMemoryCard needs information on how much time has passed since the last write
|
||||
sioNextFrame();
|
||||
#endif
|
||||
|
||||
frameLimit(); // limit FPS
|
||||
|
||||
|
|
|
@ -611,6 +611,10 @@ void AppConfig::LoadSaveMemcards( IniInterface& ini )
|
|||
Mcd[slot].Enabled, Mcd[slot].Enabled );
|
||||
ini.Entry( pxsFmt( L"Slot%u_Filename", slot+1 ),
|
||||
Mcd[slot].Filename, Mcd[slot].Filename );
|
||||
int type = (int)Mcd[slot].Type;
|
||||
ini.Entry( pxsFmt( L"Slot%u_Type", slot + 1 ),
|
||||
type, (int)MemoryCardType::MemoryCard_File );
|
||||
Mcd[slot].Type = (MemoryCardType)type;
|
||||
}
|
||||
|
||||
for( uint slot=2; slot<8; ++slot )
|
||||
|
@ -622,6 +626,10 @@ void AppConfig::LoadSaveMemcards( IniInterface& ini )
|
|||
Mcd[slot].Enabled, Mcd[slot].Enabled );
|
||||
ini.Entry( pxsFmt( L"Multitap%u_Slot%u_Filename", mtport, mtslot ),
|
||||
Mcd[slot].Filename, Mcd[slot].Filename );
|
||||
int type = (int)Mcd[slot].Type;
|
||||
ini.Entry( pxsFmt( L"Multitap%u_Slot%u_Type", mtport, mtslot ),
|
||||
type, (int)MemoryCardType::MemoryCard_File );
|
||||
Mcd[slot].Type = (MemoryCardType)type;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,6 +98,14 @@ enum AspectRatioType
|
|||
AspectRatio_MaxCount
|
||||
};
|
||||
|
||||
enum MemoryCardType
|
||||
{
|
||||
MemoryCard_None,
|
||||
MemoryCard_File,
|
||||
MemoryCard_Folder,
|
||||
MemoryCard_MaxCount
|
||||
};
|
||||
|
||||
// =====================================================================================================
|
||||
// Pcsx2 Application Configuration.
|
||||
// =====================================================================================================
|
||||
|
@ -182,6 +190,7 @@ public:
|
|||
{
|
||||
wxFileName Filename; // user-configured location of this memory card
|
||||
bool Enabled; // memory card enabled (if false, memcard will not show up in-game)
|
||||
MemoryCardType Type; // the memory card implementation that should be used
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
|
@ -154,17 +154,31 @@ void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
|
|||
}
|
||||
|
||||
wxString fullPath = ( m_mcdpath + composedName ).GetFullPath();
|
||||
if ( m_radio_CardSize && m_radio_CardSize->SelectedItem().SomeInt == 0 ) {
|
||||
// user selected to create a folder memory card
|
||||
if ( !wxFileName::Mkdir( fullPath ) ) {
|
||||
Msgbox::Alert(
|
||||
_( "Error: The directory for the memory card could not be created." ),
|
||||
_( "Create memory card" )
|
||||
);
|
||||
} else {
|
||||
// also create an empty superblock so we can recognize memory card folders based on if they have a superblock
|
||||
wxFFile superblock( wxFileName( fullPath, L"_pcsx2_superblock" ).GetFullPath(), L"wb" );
|
||||
superblock.Close();
|
||||
}
|
||||
} else {
|
||||
// otherwise create a file
|
||||
if ( !CreateIt(
|
||||
fullPath,
|
||||
m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8
|
||||
) )
|
||||
{
|
||||
) ) {
|
||||
Msgbox::Alert(
|
||||
_( "Error: The memory card could not be created." ),
|
||||
_( "Create memory card" )
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result_createdMcdFilename = composedName;
|
||||
EndModal( wxID_OK );
|
||||
|
@ -205,7 +219,11 @@ void Dialogs::CreateMemoryCardDialog::CreateControls()
|
|||
|
||||
RadioPanelItem(_("64 MB"), _("Low compatibility warning: Yes it's very big, but may not work with many games."))
|
||||
. SetToolTip(_t("Use at your own risk. Erratic memory card behavior is possible (though unlikely)."))
|
||||
. SetInt(64)
|
||||
. SetInt(64),
|
||||
|
||||
RadioPanelItem(_("Folder [experimental]"), _("Store memory card contents in the host filesystem instead of a file."))
|
||||
. SetToolTip(_t("Automatically manages memory card contents so that the console only sees files related to the currently running software. Allows you to drag-and-drop files in and out of the memory card with your standard file explorer. This is still experimental, so use at your own risk!"))
|
||||
. SetInt(0)
|
||||
};
|
||||
|
||||
m_radio_CardSize = new pxRadioPanel( this, tbl_CardSizes );
|
||||
|
|
|
@ -75,6 +75,8 @@ 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 );
|
||||
|
@ -171,7 +173,12 @@ void FileMemoryCard::Open()
|
|||
cont = true;
|
||||
}
|
||||
|
||||
Console.WriteLn( cont ? Color_Gray : Color_Green, L"McdSlot %u: " + str, slot );
|
||||
if ( g_Conf->Mcd[slot].Type != MemoryCardType::MemoryCard_File ) {
|
||||
str = L"[is not memcard file]";
|
||||
cont = true;
|
||||
}
|
||||
|
||||
Console.WriteLn( cont ? Color_Gray : Color_Green, L"McdSlot %u [File]: " + str, slot );
|
||||
if( cont ) continue;
|
||||
|
||||
const wxULongLong fsz = fname.GetSize();
|
||||
|
@ -401,6 +408,11 @@ u64 FileMemoryCard::GetCRC( uint slot )
|
|||
return retval;
|
||||
}
|
||||
|
||||
void FileMemoryCard::NextFrame( uint slot )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// MemoryCard Component API Bindings
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
@ -408,11 +420,8 @@ u64 FileMemoryCard::GetCRC( uint slot )
|
|||
struct Component_FileMcd
|
||||
{
|
||||
PS2E_ComponentAPI_Mcd api; // callbacks the plugin provides back to the emulator
|
||||
#ifdef MEMORYCARD_USE_FOLDER
|
||||
FolderMemoryCardAggregator impl;
|
||||
#else
|
||||
FileMemoryCard impl; // class-based implementations we refer to when API is invoked
|
||||
#endif
|
||||
FolderMemoryCardAggregator implFolder;
|
||||
|
||||
Component_FileMcd();
|
||||
};
|
||||
|
@ -427,52 +436,120 @@ uint FileMcd_ConvertToSlot( uint port, uint slot )
|
|||
static void PS2E_CALLBACK FileMcd_EmuOpen( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session )
|
||||
{
|
||||
thisptr->impl.Open();
|
||||
thisptr->implFolder.Open();
|
||||
}
|
||||
|
||||
static void PS2E_CALLBACK FileMcd_EmuClose( PS2E_THISPTR thisptr )
|
||||
{
|
||||
thisptr->implFolder.Close();
|
||||
thisptr->impl.Close();
|
||||
}
|
||||
|
||||
static s32 PS2E_CALLBACK FileMcd_IsPresent( PS2E_THISPTR thisptr, uint port, uint slot )
|
||||
{
|
||||
return thisptr->impl.IsPresent( FileMcd_ConvertToSlot( port, slot ) );
|
||||
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||
case MemoryCardType::MemoryCard_File:
|
||||
return thisptr->impl.IsPresent( combinedSlot );
|
||||
case MemoryCardType::MemoryCard_Folder:
|
||||
return thisptr->implFolder.IsPresent( combinedSlot );
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void PS2E_CALLBACK FileMcd_GetSizeInfo( PS2E_THISPTR thisptr, uint port, uint slot, PS2E_McdSizeInfo* outways )
|
||||
{
|
||||
thisptr->impl.GetSizeInfo( FileMcd_ConvertToSlot( port, slot ), *outways );
|
||||
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||
case MemoryCardType::MemoryCard_File:
|
||||
thisptr->impl.GetSizeInfo( combinedSlot, *outways );
|
||||
break;
|
||||
case MemoryCardType::MemoryCard_Folder:
|
||||
thisptr->implFolder.GetSizeInfo( combinedSlot, *outways );
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static bool PS2E_CALLBACK FileMcd_IsPSX( PS2E_THISPTR thisptr, uint port, uint slot )
|
||||
{
|
||||
return thisptr->impl.IsPSX( FileMcd_ConvertToSlot( port, slot ) );
|
||||
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||
case MemoryCardType::MemoryCard_File:
|
||||
return thisptr->impl.IsPSX( combinedSlot );
|
||||
case MemoryCardType::MemoryCard_Folder:
|
||||
return thisptr->implFolder.IsPSX( combinedSlot );
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static s32 PS2E_CALLBACK FileMcd_Read( PS2E_THISPTR thisptr, uint port, uint slot, u8 *dest, u32 adr, int size )
|
||||
{
|
||||
return thisptr->impl.Read( FileMcd_ConvertToSlot( port, slot ), dest, adr, size );
|
||||
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||
case MemoryCardType::MemoryCard_File:
|
||||
return thisptr->impl.Read( combinedSlot, dest, adr, size );
|
||||
case MemoryCardType::MemoryCard_Folder:
|
||||
return thisptr->implFolder.Read( combinedSlot, dest, adr, size );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static s32 PS2E_CALLBACK FileMcd_Save( PS2E_THISPTR thisptr, uint port, uint slot, const u8 *src, u32 adr, int size )
|
||||
{
|
||||
return thisptr->impl.Save( FileMcd_ConvertToSlot( port, slot ), src, adr, size );
|
||||
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||
case MemoryCardType::MemoryCard_File:
|
||||
return thisptr->impl.Save( combinedSlot, src, adr, size );
|
||||
case MemoryCardType::MemoryCard_Folder:
|
||||
return thisptr->implFolder.Save( combinedSlot, src, adr, size );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static s32 PS2E_CALLBACK FileMcd_EraseBlock( PS2E_THISPTR thisptr, uint port, uint slot, u32 adr )
|
||||
{
|
||||
return thisptr->impl.EraseBlock( FileMcd_ConvertToSlot( port, slot ), adr );
|
||||
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||
case MemoryCardType::MemoryCard_File:
|
||||
return thisptr->impl.EraseBlock( combinedSlot, adr );
|
||||
case MemoryCardType::MemoryCard_Folder:
|
||||
return thisptr->implFolder.EraseBlock( combinedSlot, adr );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static u64 PS2E_CALLBACK FileMcd_GetCRC( PS2E_THISPTR thisptr, uint port, uint slot )
|
||||
{
|
||||
return thisptr->impl.GetCRC( FileMcd_ConvertToSlot( port, slot ) );
|
||||
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||
case MemoryCardType::MemoryCard_File:
|
||||
return thisptr->impl.GetCRC( combinedSlot );
|
||||
case MemoryCardType::MemoryCard_Folder:
|
||||
return thisptr->implFolder.GetCRC( combinedSlot );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void PS2E_CALLBACK FileMcd_NextFrame( PS2E_THISPTR thisptr, uint port, uint slot ) {
|
||||
#ifdef MEMORYCARD_USE_FOLDER
|
||||
thisptr->impl.NextFrame( FileMcd_ConvertToSlot( port, slot ) );
|
||||
#endif
|
||||
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_Folder:
|
||||
thisptr->implFolder.NextFrame( combinedSlot );
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Component_FileMcd::Component_FileMcd()
|
||||
|
@ -586,6 +663,11 @@ bool isValidNewFilename( wxString filenameStringToTest, wxDirName atBasePath, wx
|
|||
out_errorMessage = _("File name already exists");
|
||||
return false;
|
||||
}
|
||||
if ( wxDirExists( (atBasePath + wxFileName(filenameStringToTest)).GetFullPath() ))
|
||||
{
|
||||
out_errorMessage = _( "File name already exists" );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxFile fp;
|
||||
if( !fp.Create( (atBasePath + wxFileName(filenameStringToTest)).GetFullPath() ))
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// define this to use the FolderMemoryCard implementation instead of the regular FileMemoryCard one
|
||||
//#define MEMORYCARD_USE_FOLDER
|
||||
|
||||
// NOTICE! This file is intended as a temporary placebo only, until such time that the
|
||||
// memorycard system is properly extracted into a plugin system (which would make it a
|
||||
// separate project file).
|
||||
|
|
|
@ -54,13 +54,14 @@ bool EnumerateMemoryCard( McdSlotItem& dest, const wxFileName& filename, const w
|
|||
{
|
||||
dest.IsFormatted = false;
|
||||
dest.IsPresent = false;
|
||||
dest.Type = MemoryCardType::MemoryCard_None;
|
||||
|
||||
const wxString fullpath( filename.GetFullPath() );
|
||||
if( !filename.FileExists() ) return false;
|
||||
|
||||
//DevCon.WriteLn( fullpath );
|
||||
if ( filename.FileExists() ) {
|
||||
// might be a memory card file
|
||||
wxFFile mcdFile( fullpath );
|
||||
if( !mcdFile.IsOpened() ) return false; // wx should log the error for us.
|
||||
if ( !mcdFile.IsOpened() ) { return false; } // wx should log the error for us.
|
||||
|
||||
wxFileOffset length = mcdFile.Length();
|
||||
|
||||
|
@ -70,21 +71,37 @@ bool EnumerateMemoryCard( McdSlotItem& dest, const wxFileName& filename, const w
|
|||
return false;
|
||||
}
|
||||
|
||||
dest.IsPresent = true;
|
||||
dest.Filename = filename;
|
||||
if( filename.GetFullPath() == (basePath+filename.GetFullName()).GetFullPath() )
|
||||
dest.Filename = filename.GetFullName();
|
||||
|
||||
dest.SizeInMB = (uint)( length / ( 1024 * 528 * 2 ) );
|
||||
|
||||
if(length == 0x20000)
|
||||
{
|
||||
if ( length == 0x20000 ) {
|
||||
dest.IsPSX = true; // PSX memcard;
|
||||
dest.SizeInMB = 1; // MegaBIT
|
||||
}
|
||||
|
||||
dest.Type = MemoryCardType::MemoryCard_File;
|
||||
dest.IsFormatted = IsMcdFormatted( mcdFile );
|
||||
filename.GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
|
||||
} else if ( filename.DirExists() ) {
|
||||
// might be a memory card folder
|
||||
wxFileName superBlockFileName( fullpath, L"_pcsx2_superblock" );
|
||||
if ( !superBlockFileName.FileExists() ) { return false; }
|
||||
wxFFile mcdFile( superBlockFileName.GetFullPath() );
|
||||
if ( !mcdFile.IsOpened() ) { return false; }
|
||||
|
||||
dest.SizeInMB = 0;
|
||||
|
||||
dest.Type = MemoryCardType::MemoryCard_Folder;
|
||||
dest.IsFormatted = IsMcdFormatted( mcdFile );
|
||||
superBlockFileName.GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
|
||||
} else {
|
||||
// is neither
|
||||
return false;
|
||||
}
|
||||
|
||||
dest.IsPresent = true;
|
||||
dest.Filename = filename;
|
||||
if( filename.GetFullPath() == (basePath+filename.GetFullName()).GetFullPath() )
|
||||
dest.Filename = filename.GetFullName();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -595,6 +612,7 @@ void Panels::MemoryCardListPanel_Simple::Apply()
|
|||
Console.WriteLn( L"Apply Memory cards:" );
|
||||
for( uint slot=0; slot<8; ++slot )
|
||||
{
|
||||
g_Conf->Mcd[slot].Type = m_Cards[slot].Type;
|
||||
g_Conf->Mcd[slot].Enabled = m_Cards[slot].IsEnabled && m_Cards[slot].IsPresent;
|
||||
if (m_Cards[slot].IsPresent)
|
||||
g_Conf->Mcd[slot].Filename = m_Cards[slot].Filename;
|
||||
|
@ -623,7 +641,7 @@ void Panels::MemoryCardListPanel_Simple::AppStatusEvent_OnSettingsApplied()
|
|||
|
||||
//automatically create the enabled but non-existing file such that it can be managed (else will get created anyway on boot)
|
||||
wxString targetFile = (GetMcdPath() + m_Cards[slot].Filename.GetFullName()).GetFullPath();
|
||||
if ( m_Cards[slot].IsEnabled && !wxFileExists( targetFile ) )
|
||||
if ( m_Cards[slot].IsEnabled && !( wxFileExists( targetFile ) || wxDirExists( targetFile ) ) )
|
||||
{
|
||||
wxString errMsg;
|
||||
if (isValidNewFilename(m_Cards[slot].Filename.GetFullName(), GetMcdPath(), errMsg, 5))
|
||||
|
@ -639,7 +657,7 @@ void Panels::MemoryCardListPanel_Simple::AppStatusEvent_OnSettingsApplied()
|
|||
}
|
||||
}
|
||||
|
||||
if ( !m_Cards[slot].IsEnabled || !wxFileExists( targetFile ) )
|
||||
if ( !m_Cards[slot].IsEnabled || !( wxFileExists( targetFile ) || wxDirExists( targetFile ) ) )
|
||||
{
|
||||
m_Cards[slot].IsEnabled = false;
|
||||
m_Cards[slot].IsPresent = false;
|
||||
|
@ -728,6 +746,72 @@ void Panels::MemoryCardListPanel_Simple::UiCreateNewCard( McdSlotItem& card )
|
|||
closed_core.AllowResume();
|
||||
}
|
||||
|
||||
bool CopyDirectory( const wxString& from, const wxString& to ) {
|
||||
wxDir src( from );
|
||||
if ( !src.IsOpened() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wxMkdir( to );
|
||||
wxDir dst( to );
|
||||
if ( !dst.IsOpened() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString filename;
|
||||
|
||||
// copy directories
|
||||
if ( src.GetFirst( &filename, wxEmptyString, wxDIR_DIRS | wxDIR_HIDDEN ) ) {
|
||||
do {
|
||||
if ( !CopyDirectory( wxFileName( from, filename ).GetFullPath(), wxFileName( to, filename ).GetFullPath() ) ) {
|
||||
return false;
|
||||
}
|
||||
} while ( src.GetNext( &filename ) );
|
||||
}
|
||||
|
||||
// copy files
|
||||
if ( src.GetFirst( &filename, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN ) ) {
|
||||
do {
|
||||
if ( !wxCopyFile( wxFileName( from, filename ).GetFullPath(), wxFileName( to, filename ).GetFullPath() ) ) {
|
||||
return false;
|
||||
}
|
||||
} while ( src.GetNext( &filename ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemoveDirectory( const wxString& dirname ) {
|
||||
{
|
||||
wxDir dir( dirname );
|
||||
if ( !dir.IsOpened() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString filename;
|
||||
|
||||
// delete subdirs recursively
|
||||
if ( dir.GetFirst( &filename, wxEmptyString, wxDIR_DIRS | wxDIR_HIDDEN ) ) {
|
||||
do {
|
||||
if ( !RemoveDirectory( wxFileName( dirname, filename ).GetFullPath() ) ) {
|
||||
return false;
|
||||
}
|
||||
} while ( dir.GetNext( &filename ) );
|
||||
}
|
||||
|
||||
// delete files
|
||||
if ( dir.GetFirst( &filename, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN ) ) {
|
||||
do {
|
||||
if ( !wxRemoveFile( wxFileName( dirname, filename ).GetFullPath() ) ) {
|
||||
return false;
|
||||
}
|
||||
} while ( dir.GetNext( &filename ) );
|
||||
}
|
||||
}
|
||||
|
||||
// oddly enough this has different results compared to the more sensible dirname.Rmdir(), don't change!
|
||||
return wxFileName::Rmdir( dirname );
|
||||
}
|
||||
|
||||
void Panels::MemoryCardListPanel_Simple::UiDeleteCard( McdSlotItem& card )
|
||||
{
|
||||
|
@ -757,7 +841,12 @@ void Panels::MemoryCardListPanel_Simple::UiDeleteCard( McdSlotItem& card )
|
|||
|
||||
card.IsEnabled=false;
|
||||
Apply();
|
||||
|
||||
if ( fullpath.FileExists() ) {
|
||||
wxRemoveFile( fullpath.GetFullPath() );
|
||||
} else {
|
||||
RemoveDirectory( fullpath.GetFullPath() );
|
||||
}
|
||||
|
||||
RefreshSelections();
|
||||
closed_core.AllowResume();
|
||||
|
@ -817,7 +906,8 @@ bool Panels::MemoryCardListPanel_Simple::UiDuplicateCard(McdSlotItem& src, McdSl
|
|||
ScopedBusyCursor doh( Cursor_ReallyBusy );
|
||||
ScopedCoreThreadClose closed_core;
|
||||
|
||||
if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
|
||||
if( !( ( srcfile.FileExists() && wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
|
||||
|| ( !srcfile.FileExists() && CopyDirectory( srcfile.GetFullPath(), destfile.GetFullPath() ) ) ) )
|
||||
{
|
||||
wxString heading;
|
||||
heading.Printf( pxE( L"Failed: Destination memory card '%s' is in use." ),
|
||||
|
@ -1106,9 +1196,26 @@ void Panels::MemoryCardListPanel_Simple::ReadFilesAtMcdFolder(){
|
|||
|
||||
|
||||
wxArrayString memcardList;
|
||||
wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), &memcardList, L"*.ps2", wxDIR_FILES);
|
||||
wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), &memcardList, L"*.mcd", wxDIR_FILES);
|
||||
wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), &memcardList, L"*.mcr", wxDIR_FILES);
|
||||
wxString filename = m_FolderPicker->GetPath().ToString();
|
||||
wxDir memcardDir( filename );
|
||||
if ( memcardDir.IsOpened() ) {
|
||||
// add memory card files
|
||||
wxDir::GetAllFiles( filename, &memcardList, L"*.ps2", wxDIR_FILES );
|
||||
wxDir::GetAllFiles( filename, &memcardList, L"*.mcd", wxDIR_FILES );
|
||||
wxDir::GetAllFiles( filename, &memcardList, L"*.mcr", wxDIR_FILES );
|
||||
|
||||
// add memory card folders
|
||||
wxString dirname;
|
||||
if ( memcardDir.GetFirst( &dirname, wxEmptyString, wxDIR_DIRS | wxDIR_HIDDEN ) ) {
|
||||
do {
|
||||
wxFileName superBlockFileName( wxFileName( filename, dirname ).GetFullPath(), L"_pcsx2_superblock" );
|
||||
if ( superBlockFileName.FileExists() ) {
|
||||
memcardList.Add( superBlockFileName.GetPath() );
|
||||
}
|
||||
} while ( memcardDir.GetNext( &dirname ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(uint i = 0; i < memcardList.size(); i++) {
|
||||
McdSlotItem currentCardFile;
|
||||
|
|
|
@ -156,7 +156,7 @@ wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
|
|||
return prefix + res;
|
||||
}
|
||||
*/
|
||||
case McdColS_Size: return prefix + ( !it.IsPresent ? L"" : (it.IsPSX? pxsFmt( L"%u MBit", it.SizeInMB ) : pxsFmt( L"%u MiB", it.SizeInMB )) );
|
||||
case McdColS_Size: return prefix + ( !it.IsPresent ? L"" : (it.IsPSX? pxsFmt( L"%u MBit", it.SizeInMB ) : ( it.SizeInMB > 0 ? pxsFmt( L"%u MiB", it.SizeInMB ) : L"Auto" ) ) );
|
||||
case McdColS_Formatted: return prefix + ( !it.IsPresent ? L"" : ( it.IsFormatted ? _("Yes") : _("No")) );
|
||||
case McdColS_Type: return prefix + ( !it.IsPresent ? L"" : ( it.IsPSX? _("PSX") : _("PS2")) );
|
||||
case McdColS_DateModified: return prefix + ( !it.IsPresent ? L"" : it.DateModified.FormatDate() );
|
||||
|
|
|
@ -40,6 +40,7 @@ struct McdSlotItem
|
|||
{
|
||||
int Slot; //0-7: internal slot. -1: unrelated to an internal slot (the rest of the files at the folder).
|
||||
bool IsPresent; //Whether or not a file is associated with this item (true/false when 0<=Slot<=7. Always true when Slot==-1)
|
||||
MemoryCardType Type; //The implementation used for this memory card
|
||||
|
||||
//Only meaningful when IsPresent==true (a file exists for this item):
|
||||
wxFileName Filename; // full pathname
|
||||
|
|
Loading…
Reference in New Issue