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
|
psxVBlankEnd(); // psxCounters vBlank End
|
||||||
if (gates) rcntEndGate(true, sCycle); // Counters End Gate Code
|
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
|
// FolderMemoryCard needs information on how much time has passed since the last write
|
||||||
sioNextFrame();
|
sioNextFrame();
|
||||||
#endif
|
|
||||||
|
|
||||||
frameLimit(); // limit FPS
|
frameLimit(); // limit FPS
|
||||||
|
|
||||||
|
|
|
@ -611,6 +611,10 @@ void AppConfig::LoadSaveMemcards( IniInterface& ini )
|
||||||
Mcd[slot].Enabled, Mcd[slot].Enabled );
|
Mcd[slot].Enabled, Mcd[slot].Enabled );
|
||||||
ini.Entry( pxsFmt( L"Slot%u_Filename", slot+1 ),
|
ini.Entry( pxsFmt( L"Slot%u_Filename", slot+1 ),
|
||||||
Mcd[slot].Filename, Mcd[slot].Filename );
|
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 )
|
for( uint slot=2; slot<8; ++slot )
|
||||||
|
@ -622,6 +626,10 @@ void AppConfig::LoadSaveMemcards( IniInterface& ini )
|
||||||
Mcd[slot].Enabled, Mcd[slot].Enabled );
|
Mcd[slot].Enabled, Mcd[slot].Enabled );
|
||||||
ini.Entry( pxsFmt( L"Multitap%u_Slot%u_Filename", mtport, mtslot ),
|
ini.Entry( pxsFmt( L"Multitap%u_Slot%u_Filename", mtport, mtslot ),
|
||||||
Mcd[slot].Filename, Mcd[slot].Filename );
|
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
|
AspectRatio_MaxCount
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum MemoryCardType
|
||||||
|
{
|
||||||
|
MemoryCard_None,
|
||||||
|
MemoryCard_File,
|
||||||
|
MemoryCard_Folder,
|
||||||
|
MemoryCard_MaxCount
|
||||||
|
};
|
||||||
|
|
||||||
// =====================================================================================================
|
// =====================================================================================================
|
||||||
// Pcsx2 Application Configuration.
|
// Pcsx2 Application Configuration.
|
||||||
// =====================================================================================================
|
// =====================================================================================================
|
||||||
|
@ -182,6 +190,7 @@ public:
|
||||||
{
|
{
|
||||||
wxFileName Filename; // user-configured location of this memory card
|
wxFileName Filename; // user-configured location of this memory card
|
||||||
bool Enabled; // memory card enabled (if false, memcard will not show up in-game)
|
bool Enabled; // memory card enabled (if false, memcard will not show up in-game)
|
||||||
|
MemoryCardType Type; // the memory card implementation that should be used
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
|
@ -153,17 +153,31 @@ void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString fullPath=(m_mcdpath + composedName).GetFullPath();
|
wxString fullPath = ( m_mcdpath + composedName ).GetFullPath();
|
||||||
if( !CreateIt(
|
if ( m_radio_CardSize && m_radio_CardSize->SelectedItem().SomeInt == 0 ) {
|
||||||
fullPath,
|
// user selected to create a folder memory card
|
||||||
m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8
|
if ( !wxFileName::Mkdir( fullPath ) ) {
|
||||||
) )
|
Msgbox::Alert(
|
||||||
{
|
_( "Error: The directory for the memory card could not be created." ),
|
||||||
Msgbox::Alert(
|
_( "Create memory card" )
|
||||||
_("Error: 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
|
||||||
return;
|
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;
|
result_createdMcdFilename = composedName;
|
||||||
|
@ -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."))
|
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)."))
|
. 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 );
|
m_radio_CardSize = new pxRadioPanel( this, tbl_CardSizes );
|
||||||
|
|
|
@ -75,6 +75,8 @@ public:
|
||||||
s32 EraseBlock ( uint slot, u32 adr );
|
s32 EraseBlock ( uint slot, u32 adr );
|
||||||
u64 GetCRC ( uint slot );
|
u64 GetCRC ( uint slot );
|
||||||
|
|
||||||
|
void NextFrame( uint slot );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool Seek( wxFFile& f, u32 adr );
|
bool Seek( wxFFile& f, u32 adr );
|
||||||
bool Create( const wxString& mcdFile, uint sizeInMB );
|
bool Create( const wxString& mcdFile, uint sizeInMB );
|
||||||
|
@ -171,7 +173,12 @@ void FileMemoryCard::Open()
|
||||||
cont = true;
|
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;
|
if( cont ) continue;
|
||||||
|
|
||||||
const wxULongLong fsz = fname.GetSize();
|
const wxULongLong fsz = fname.GetSize();
|
||||||
|
@ -401,18 +408,20 @@ u64 FileMemoryCard::GetCRC( uint slot )
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileMemoryCard::NextFrame( uint slot )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// MemoryCard Component API Bindings
|
// MemoryCard Component API Bindings
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct Component_FileMcd
|
struct Component_FileMcd
|
||||||
{
|
{
|
||||||
PS2E_ComponentAPI_Mcd api; // callbacks the plugin provides back to the emulator
|
PS2E_ComponentAPI_Mcd api; // callbacks the plugin provides back to the emulator
|
||||||
#ifdef MEMORYCARD_USE_FOLDER
|
FileMemoryCard impl; // class-based implementations we refer to when API is invoked
|
||||||
FolderMemoryCardAggregator impl;
|
FolderMemoryCardAggregator implFolder;
|
||||||
#else
|
|
||||||
FileMemoryCard impl; // class-based implementations we refer to when API is invoked
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Component_FileMcd();
|
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 )
|
static void PS2E_CALLBACK FileMcd_EmuOpen( PS2E_THISPTR thisptr, const PS2E_SessionInfo *session )
|
||||||
{
|
{
|
||||||
thisptr->impl.Open();
|
thisptr->impl.Open();
|
||||||
|
thisptr->implFolder.Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PS2E_CALLBACK FileMcd_EmuClose( PS2E_THISPTR thisptr )
|
static void PS2E_CALLBACK FileMcd_EmuClose( PS2E_THISPTR thisptr )
|
||||||
{
|
{
|
||||||
|
thisptr->implFolder.Close();
|
||||||
thisptr->impl.Close();
|
thisptr->impl.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
static s32 PS2E_CALLBACK FileMcd_IsPresent( PS2E_THISPTR thisptr, uint port, uint slot )
|
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 )
|
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 )
|
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 )
|
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 )
|
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 )
|
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 )
|
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 ) {
|
static void PS2E_CALLBACK FileMcd_NextFrame( PS2E_THISPTR thisptr, uint port, uint slot ) {
|
||||||
#ifdef MEMORYCARD_USE_FOLDER
|
const uint combinedSlot = FileMcd_ConvertToSlot( port, slot );
|
||||||
thisptr->impl.NextFrame( FileMcd_ConvertToSlot( port, slot ) );
|
switch ( g_Conf->Mcd[combinedSlot].Type ) {
|
||||||
#endif
|
case MemoryCardType::MemoryCard_File:
|
||||||
|
thisptr->impl.NextFrame( combinedSlot );
|
||||||
|
break;
|
||||||
|
case MemoryCardType::MemoryCard_Folder:
|
||||||
|
thisptr->implFolder.NextFrame( combinedSlot );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component_FileMcd::Component_FileMcd()
|
Component_FileMcd::Component_FileMcd()
|
||||||
|
@ -586,6 +663,11 @@ bool isValidNewFilename( wxString filenameStringToTest, wxDirName atBasePath, wx
|
||||||
out_errorMessage = _("File name already exists");
|
out_errorMessage = _("File name already exists");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ( wxDirExists( (atBasePath + wxFileName(filenameStringToTest)).GetFullPath() ))
|
||||||
|
{
|
||||||
|
out_errorMessage = _( "File name already exists" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
wxFile fp;
|
wxFile fp;
|
||||||
if( !fp.Create( (atBasePath + wxFileName(filenameStringToTest)).GetFullPath() ))
|
if( !fp.Create( (atBasePath + wxFileName(filenameStringToTest)).GetFullPath() ))
|
||||||
|
|
|
@ -15,9 +15,6 @@
|
||||||
|
|
||||||
#pragma once
|
#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
|
// 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
|
// memorycard system is properly extracted into a plugin system (which would make it a
|
||||||
// separate project file).
|
// separate project file).
|
||||||
|
|
|
@ -54,19 +54,47 @@ bool EnumerateMemoryCard( McdSlotItem& dest, const wxFileName& filename, const w
|
||||||
{
|
{
|
||||||
dest.IsFormatted = false;
|
dest.IsFormatted = false;
|
||||||
dest.IsPresent = false;
|
dest.IsPresent = false;
|
||||||
|
dest.Type = MemoryCardType::MemoryCard_None;
|
||||||
|
|
||||||
const wxString fullpath( filename.GetFullPath() );
|
const wxString fullpath( filename.GetFullPath() );
|
||||||
if( !filename.FileExists() ) return false;
|
|
||||||
|
|
||||||
//DevCon.WriteLn( fullpath );
|
//DevCon.WriteLn( fullpath );
|
||||||
wxFFile mcdFile( fullpath );
|
if ( filename.FileExists() ) {
|
||||||
if( !mcdFile.IsOpened() ) return false; // wx should log the error for us.
|
// might be a memory card file
|
||||||
|
wxFFile mcdFile( fullpath );
|
||||||
|
if ( !mcdFile.IsOpened() ) { return false; } // wx should log the error for us.
|
||||||
|
|
||||||
wxFileOffset length = mcdFile.Length();
|
wxFileOffset length = mcdFile.Length();
|
||||||
|
|
||||||
if( length < (1024*528) && length != 0x20000 )
|
if( length < (1024*528) && length != 0x20000 )
|
||||||
{
|
{
|
||||||
Console.Warning( "... MemoryCard appears to be truncated. Ignoring." );
|
Console.Warning( "... MemoryCard appears to be truncated. Ignoring." );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.SizeInMB = (uint)( length / ( 1024 * 528 * 2 ) );
|
||||||
|
|
||||||
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,17 +103,6 @@ bool EnumerateMemoryCard( McdSlotItem& dest, const wxFileName& filename, const w
|
||||||
if( filename.GetFullPath() == (basePath+filename.GetFullName()).GetFullPath() )
|
if( filename.GetFullPath() == (basePath+filename.GetFullName()).GetFullPath() )
|
||||||
dest.Filename = filename.GetFullName();
|
dest.Filename = filename.GetFullName();
|
||||||
|
|
||||||
dest.SizeInMB = (uint)(length / (1024 * 528 * 2));
|
|
||||||
|
|
||||||
if(length == 0x20000)
|
|
||||||
{
|
|
||||||
dest.IsPSX = true; // PSX memcard;
|
|
||||||
dest.SizeInMB = 1; // MegaBIT
|
|
||||||
}
|
|
||||||
|
|
||||||
dest.IsFormatted = IsMcdFormatted( mcdFile );
|
|
||||||
filename.GetTimes( NULL, &dest.DateModified, &dest.DateCreated );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,6 +612,7 @@ void Panels::MemoryCardListPanel_Simple::Apply()
|
||||||
Console.WriteLn( L"Apply Memory cards:" );
|
Console.WriteLn( L"Apply Memory cards:" );
|
||||||
for( uint slot=0; slot<8; ++slot )
|
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;
|
g_Conf->Mcd[slot].Enabled = m_Cards[slot].IsEnabled && m_Cards[slot].IsPresent;
|
||||||
if (m_Cards[slot].IsPresent)
|
if (m_Cards[slot].IsPresent)
|
||||||
g_Conf->Mcd[slot].Filename = m_Cards[slot].Filename;
|
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)
|
//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();
|
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;
|
wxString errMsg;
|
||||||
if (isValidNewFilename(m_Cards[slot].Filename.GetFullName(), GetMcdPath(), errMsg, 5))
|
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].IsEnabled = false;
|
||||||
m_Cards[slot].IsPresent = false;
|
m_Cards[slot].IsPresent = false;
|
||||||
|
@ -728,6 +746,72 @@ void Panels::MemoryCardListPanel_Simple::UiCreateNewCard( McdSlotItem& card )
|
||||||
closed_core.AllowResume();
|
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 )
|
void Panels::MemoryCardListPanel_Simple::UiDeleteCard( McdSlotItem& card )
|
||||||
{
|
{
|
||||||
|
@ -757,7 +841,12 @@ void Panels::MemoryCardListPanel_Simple::UiDeleteCard( McdSlotItem& card )
|
||||||
|
|
||||||
card.IsEnabled=false;
|
card.IsEnabled=false;
|
||||||
Apply();
|
Apply();
|
||||||
wxRemoveFile( fullpath.GetFullPath() );
|
|
||||||
|
if ( fullpath.FileExists() ) {
|
||||||
|
wxRemoveFile( fullpath.GetFullPath() );
|
||||||
|
} else {
|
||||||
|
RemoveDirectory( fullpath.GetFullPath() );
|
||||||
|
}
|
||||||
|
|
||||||
RefreshSelections();
|
RefreshSelections();
|
||||||
closed_core.AllowResume();
|
closed_core.AllowResume();
|
||||||
|
@ -817,7 +906,8 @@ bool Panels::MemoryCardListPanel_Simple::UiDuplicateCard(McdSlotItem& src, McdSl
|
||||||
ScopedBusyCursor doh( Cursor_ReallyBusy );
|
ScopedBusyCursor doh( Cursor_ReallyBusy );
|
||||||
ScopedCoreThreadClose closed_core;
|
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;
|
wxString heading;
|
||||||
heading.Printf( pxE( L"Failed: Destination memory card '%s' is in use." ),
|
heading.Printf( pxE( L"Failed: Destination memory card '%s' is in use." ),
|
||||||
|
@ -1106,9 +1196,26 @@ void Panels::MemoryCardListPanel_Simple::ReadFilesAtMcdFolder(){
|
||||||
|
|
||||||
|
|
||||||
wxArrayString memcardList;
|
wxArrayString memcardList;
|
||||||
wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), &memcardList, L"*.ps2", wxDIR_FILES);
|
wxString filename = m_FolderPicker->GetPath().ToString();
|
||||||
wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), &memcardList, L"*.mcd", wxDIR_FILES);
|
wxDir memcardDir( filename );
|
||||||
wxDir::GetAllFiles(m_FolderPicker->GetPath().ToString(), &memcardList, L"*.mcr", wxDIR_FILES);
|
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++) {
|
for(uint i = 0; i < memcardList.size(); i++) {
|
||||||
McdSlotItem currentCardFile;
|
McdSlotItem currentCardFile;
|
||||||
|
|
|
@ -156,7 +156,7 @@ wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
|
||||||
return prefix + res;
|
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_Formatted: return prefix + ( !it.IsPresent ? L"" : ( it.IsFormatted ? _("Yes") : _("No")) );
|
||||||
case McdColS_Type: return prefix + ( !it.IsPresent ? L"" : ( it.IsPSX? _("PSX") : _("PS2")) );
|
case McdColS_Type: return prefix + ( !it.IsPresent ? L"" : ( it.IsPSX? _("PSX") : _("PS2")) );
|
||||||
case McdColS_DateModified: return prefix + ( !it.IsPresent ? L"" : it.DateModified.FormatDate() );
|
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).
|
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)
|
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):
|
//Only meaningful when IsPresent==true (a file exists for this item):
|
||||||
wxFileName Filename; // full pathname
|
wxFileName Filename; // full pathname
|
||||||
|
|
Loading…
Reference in New Issue