mirror of
https://github.com/libretro/pcsx2.git
synced 2024-12-03 23:50:49 +00:00
Even more memorycard work! Dialog box is mostly functional now (still missing a couple options and refinements) -- WARNING: settings/ini storage has changed. If you're using non-default memorycard settings, you'll need to go and edit your ini again.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3066 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
0b7bbdc723
commit
d8ba646de2
@ -29,11 +29,16 @@ struct RadioPanelItem
|
||||
wxString SubText;
|
||||
wxString ToolTip;
|
||||
|
||||
int SomeInt;
|
||||
void* SomePtr;
|
||||
|
||||
RadioPanelItem( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString )
|
||||
: Label( label )
|
||||
, SubText( subtext )
|
||||
, ToolTip( tooltip )
|
||||
{
|
||||
SomeInt = 0;
|
||||
SomePtr = NULL;
|
||||
}
|
||||
|
||||
RadioPanelItem& SetToolTip( const wxString& tip )
|
||||
@ -47,6 +52,18 @@ struct RadioPanelItem
|
||||
SubText = text;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RadioPanelItem& SetInt( int intval )
|
||||
{
|
||||
SomeInt = intval;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RadioPanelItem& SetPtr( void* ptrval )
|
||||
{
|
||||
SomePtr = ptrval;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -114,10 +131,16 @@ public:
|
||||
pxRadioPanel& SetDefaultItem( int idx );
|
||||
pxRadioPanel& EnableItem( int idx, bool enable=true );
|
||||
|
||||
const RadioPanelItem& Item(int idx) const;
|
||||
RadioPanelItem& Item(int idx);
|
||||
|
||||
int GetSelection() const;
|
||||
wxWindowID GetSelectionId() const;
|
||||
bool IsSelected( int idx ) const;
|
||||
|
||||
const RadioPanelItem& SelectedItem() const { return Item(GetSelection()); }
|
||||
RadioPanelItem& SelectedItem() { return Item(GetSelection()); }
|
||||
|
||||
wxRadioButton* GetButton( int idx );
|
||||
const wxRadioButton* GetButton( int idx ) const;
|
||||
|
||||
|
@ -307,7 +307,7 @@ protected:
|
||||
bool m_hasContextHelp;
|
||||
int m_idealWidth;
|
||||
wxBoxSizer* m_extraButtonSizer;
|
||||
|
||||
|
||||
public:
|
||||
wxDialogWithHelpers();
|
||||
wxDialogWithHelpers(wxWindow* parent, const wxString& title, bool hasContextHelp=false, bool resizable=false );
|
||||
|
@ -177,6 +177,15 @@ pxRadioPanel& pxRadioPanel::EnableItem( int idx, bool enable )
|
||||
return *this;
|
||||
}
|
||||
|
||||
const RadioPanelItem& pxRadioPanel::Item(int idx) const
|
||||
{
|
||||
return m_buttonStrings[idx];
|
||||
}
|
||||
|
||||
RadioPanelItem& pxRadioPanel::Item(int idx)
|
||||
{
|
||||
return m_buttonStrings[idx];
|
||||
}
|
||||
|
||||
int pxRadioPanel::GetSelection() const
|
||||
{
|
||||
|
@ -11,7 +11,7 @@
|
||||
!endif
|
||||
|
||||
!ifndef INC_CRT_2008
|
||||
!define INC_CRT_2008 1
|
||||
!define INC_CRT_2008 0
|
||||
!endif
|
||||
|
||||
!ifndef INC_CRT_2010
|
||||
@ -313,7 +313,13 @@ LangString DESC_DIRECTX ${LANG_ENGLISH} "Only uncheck this if you are quite c
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_STARTMENU} $(DESC_STARTMENU)
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP} $(DESC_DESKTOP)
|
||||
|
||||
!if ${INC_CRT_2008} > 0
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_CRT2008} $(DESC_CRT2008)
|
||||
!endif
|
||||
|
||||
!if ${INC_CRT_2010} > 0
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_CRT2010} $(DESC_CRT2010)
|
||||
!endif
|
||||
|
||||
!insertmacro MUI_DESCRIPTION_TEXT ${SEC_DIRECTX} $(DESC_DIRECTX)
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "IniInterface.h"
|
||||
#include "Plugins.h"
|
||||
|
||||
#include "MemoryCardFile.h"
|
||||
|
||||
#include <wx/stdpaths.h>
|
||||
#include "DebugTools/Debug.h"
|
||||
|
||||
@ -336,9 +338,9 @@ wxString GetSettingsFilename()
|
||||
|
||||
|
||||
wxString AppConfig::FullpathToBios() const { return Path::Combine( Folders.Bios, BaseFilenames.Bios ); }
|
||||
wxString AppConfig::FullpathToMcd( uint port, uint slot ) const
|
||||
wxString AppConfig::FullpathToMcd( uint slot ) const
|
||||
{
|
||||
return Path::Combine( Folders.MemoryCards, Mcd[port][slot].Filename );
|
||||
return Path::Combine( Folders.MemoryCards, Mcd[slot].Filename );
|
||||
}
|
||||
|
||||
AppConfig::AppConfig()
|
||||
@ -363,13 +365,11 @@ AppConfig::AppConfig()
|
||||
|
||||
CdvdSource = CDVDsrc_Iso;
|
||||
|
||||
for( uint port=0; port<2; ++port )
|
||||
// To be moved to FileMemoryCard pluign (someday)
|
||||
for( uint slot=0; slot<8; ++slot )
|
||||
{
|
||||
for( uint slot=0; slot<4; ++slot )
|
||||
{
|
||||
Mcd[port][slot].Enabled = (slot==0); // enables main 2 slots
|
||||
Mcd[port][slot].Filename = FilenameDefs::Memcard( port, slot );
|
||||
}
|
||||
Mcd[slot].Enabled = !FileMcd_IsMultitapSlot(slot); // enables main 2 slots
|
||||
Mcd[slot].Filename = FileMcd_GetDefaultName( slot );
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,15 +409,23 @@ void AppConfig::LoadSaveMemcards( IniInterface& ini )
|
||||
AppConfig defaults;
|
||||
IniScopedGroup path( ini, L"MemoryCards" );
|
||||
|
||||
for( uint port=0; port<2; ++port )
|
||||
for( uint slot=0; slot<2; ++slot )
|
||||
{
|
||||
for( int slot=0; slot<4; ++slot )
|
||||
{
|
||||
ini.Entry( wxsFormat( L"Port%d_Slot%d_Enable", port, slot ),
|
||||
Mcd[port][slot].Enabled, defaults.Mcd[port][slot].Enabled );
|
||||
ini.Entry( wxsFormat( L"Port%d_Slot%d_Filename", port, slot ),
|
||||
Mcd[port][slot].Filename, defaults.Mcd[port][slot].Filename );
|
||||
}
|
||||
ini.Entry( wxsFormat( L"Slot%u_Enable", slot+1 ),
|
||||
Mcd[slot].Enabled, defaults.Mcd[slot].Enabled );
|
||||
ini.Entry( wxsFormat( L"Slot%u_Filename", slot+1 ),
|
||||
Mcd[slot].Filename, defaults.Mcd[slot].Filename );
|
||||
}
|
||||
|
||||
for( uint slot=2; slot<8; ++slot )
|
||||
{
|
||||
int mtport = FileMcd_GetMtapPort(slot)+1;
|
||||
int mtslot = FileMcd_GetMtapSlot(slot)+1;
|
||||
|
||||
ini.Entry( wxsFormat( L"Multitap%u_Slot%d_Enable", mtport, mtslot ),
|
||||
Mcd[slot].Enabled, defaults.Mcd[slot].Enabled );
|
||||
ini.Entry( wxsFormat( L"Multitap%u_Slot%d_Filename", mtport, mtslot ),
|
||||
Mcd[slot].Filename, defaults.Mcd[slot].Filename );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,10 @@ public:
|
||||
wxString CurrentELF;
|
||||
CDVD_SourceType CdvdSource;
|
||||
|
||||
McdOptions Mcd[2][4];
|
||||
// Memorycard options - first 2 are default slots, last 6 are multitap 1 and 2
|
||||
// slots (3 each)
|
||||
McdOptions Mcd[8];
|
||||
|
||||
ConsoleLogOptions ProgLogBox;
|
||||
FolderOptions Folders;
|
||||
FilenameOptions BaseFilenames;
|
||||
@ -239,7 +242,7 @@ public:
|
||||
AppConfig();
|
||||
|
||||
wxString FullpathToBios() const;
|
||||
wxString FullpathToMcd( uint port, uint slot ) const;
|
||||
wxString FullpathToMcd( uint slot ) const;
|
||||
wxString FullpathTo( PluginsEnum_t pluginId ) const;
|
||||
|
||||
bool FullpathMatchTest( PluginsEnum_t pluginId, const wxString& cmpto ) const;
|
||||
@ -254,7 +257,7 @@ public:
|
||||
struct ConfigOverrides
|
||||
{
|
||||
AppConfig::FilenameOptions Filenames;
|
||||
wxString SettingsFolder;
|
||||
wxString SettingsFolder;
|
||||
};
|
||||
|
||||
extern ConfigOverrides OverrideOptions;
|
||||
|
@ -152,6 +152,10 @@ namespace Dialogs
|
||||
class CreateMemoryCardDialog : public wxDialogWithHelpers
|
||||
{
|
||||
protected:
|
||||
uint m_slot;
|
||||
wxDirName m_mcdpath;
|
||||
wxString m_mcdfile;
|
||||
|
||||
wxFilePickerCtrl* m_filepicker;
|
||||
pxRadioPanel* m_radio_CardSize;
|
||||
|
||||
@ -161,10 +165,13 @@ namespace Dialogs
|
||||
|
||||
public:
|
||||
virtual ~CreateMemoryCardDialog() throw() {}
|
||||
CreateMemoryCardDialog( wxWindow* parent, uint port, uint slot, const wxString& filepath=wxEmptyString );
|
||||
//CreateMemoryCardDialog( wxWindow* parent, uint port, uint slot, const wxString& filepath=wxEmptyString );
|
||||
CreateMemoryCardDialog( wxWindow* parent, uint port, const wxDirName& mcdpath, const wxString& mcdfile=wxEmptyString );
|
||||
|
||||
wxDirName GetPathToMcds() const;
|
||||
|
||||
protected:
|
||||
void CreateControls();
|
||||
void OnOk_Click( wxCommandEvent& evt );
|
||||
void OnDoubleClicked( wxCommandEvent& evt );
|
||||
};
|
||||
}
|
||||
|
@ -15,6 +15,9 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ConfigurationDialog.h"
|
||||
#include "System.h"
|
||||
|
||||
#include "MemoryCardFile.h"
|
||||
|
||||
#include <wx/filepicker.h>
|
||||
#include <wx/ffile.h>
|
||||
@ -38,14 +41,106 @@ wxFilePickerCtrl* CreateMemoryCardFilePicker( wxWindow* parent, uint portidx, ui
|
||||
L"Deletes the existing memory card and creates a new one. All existing card contents will be lost."
|
||||
) );*/
|
||||
|
||||
Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint port, uint slot, const wxString& filepath )
|
||||
: wxDialogWithHelpers( parent, _("Create a new MemoryCard..."), wxVERTICAL )
|
||||
Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint slot, const wxDirName& mcdpath, const wxString& mcdfile )
|
||||
: wxDialogWithHelpers( parent, _("Create new MemoryCard"), wxVERTICAL )
|
||||
, m_mcdpath( mcdpath.IsOk() ? mcdpath : (wxDirName)g_Conf->Mcd[slot].Filename.GetPath() )
|
||||
, m_mcdfile( mcdfile.IsEmpty() ? g_Conf->Mcd[slot].Filename.GetFullName() : mcdfile )
|
||||
{
|
||||
m_idealWidth = 620;
|
||||
m_idealWidth = 472;
|
||||
m_filepicker = NULL;
|
||||
m_slot = slot;
|
||||
|
||||
CreateControls();
|
||||
|
||||
//m_filepicker = CreateMemoryCardFilePicker( this, m_port, m_slot, filepath );
|
||||
|
||||
// ----------------------------
|
||||
// Sizers and Layout
|
||||
// ----------------------------
|
||||
|
||||
if( m_radio_CardSize ) m_radio_CardSize->Realize();
|
||||
|
||||
wxBoxSizer& s_buttons( *new wxBoxSizer(wxHORIZONTAL) );
|
||||
s_buttons += new wxButton( this, wxID_OK ) | pxProportion(2);
|
||||
s_buttons += pxStretchSpacer(3);
|
||||
s_buttons += new wxButton( this, wxID_CANCEL ) | pxProportion(2);
|
||||
|
||||
wxBoxSizer& s_padding( *new wxBoxSizer(wxVERTICAL) );
|
||||
*this += s_padding | StdExpand();
|
||||
|
||||
//s_padding += Heading(_("Select the size for your new MemoryCard."));
|
||||
|
||||
if( m_filepicker )
|
||||
s_padding += m_filepicker | StdExpand();
|
||||
else
|
||||
{
|
||||
s_padding += Heading( _( "(new card will be saved to:" ) );
|
||||
s_padding += Heading( (m_mcdpath + m_mcdfile).GetFullPath() );
|
||||
}
|
||||
|
||||
s_padding += m_radio_CardSize | StdExpand();
|
||||
#ifdef __WXMSW__
|
||||
if( m_check_CompressNTFS ) s_padding += m_check_CompressNTFS | StdExpand();
|
||||
#endif
|
||||
|
||||
s_padding += 12;
|
||||
s_padding += s_buttons | StdCenter();
|
||||
|
||||
*this += s_padding | StdExpand();
|
||||
|
||||
|
||||
FindItem( wxID_OK )->SetLabel(_("Create"));
|
||||
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnOk_Click ) );
|
||||
//Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( CreateMemoryCardDialog::OnApply_Click ) );
|
||||
}
|
||||
|
||||
wxDirName Dialogs::CreateMemoryCardDialog::GetPathToMcds() const
|
||||
{
|
||||
return m_filepicker ? (wxDirName)m_filepicker->GetPath() : m_mcdpath;
|
||||
}
|
||||
|
||||
// When this GUI is moved itno the FileMemoryCard plugin (where it eventually belongs),
|
||||
// this function will be removed and the MemoryCardFile::Create() function will be used
|
||||
// instead.
|
||||
static bool CreateIt( const wxString& mcdFile, uint sizeInMB )
|
||||
{
|
||||
//int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0};
|
||||
|
||||
u8 m_effeffs[528*16];
|
||||
memset8<0xff>( m_effeffs );
|
||||
|
||||
Console.WriteLn( L"(FileMcd) Creating new %uMB MemoryCard: " + mcdFile, sizeInMB );
|
||||
|
||||
wxFFile fp( mcdFile, L"wb" );
|
||||
if( !fp.IsOpened() ) return false;
|
||||
|
||||
static const int MC2_MBSIZE = 1024 * 528 * 2; // Size of a single megabyte of card data
|
||||
|
||||
for( uint i=0; i<(MC2_MBSIZE*sizeInMB)/sizeof(m_effeffs); i++ )
|
||||
{
|
||||
if( fp.Write( m_effeffs, sizeof(m_effeffs) ) == 0 )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dialogs::CreateMemoryCardDialog::OnOk_Click( wxCommandEvent& evt )
|
||||
{
|
||||
if( !CreateIt(
|
||||
m_filepicker ? m_filepicker->GetPath() : m_mcdfile,
|
||||
m_radio_CardSize ? m_radio_CardSize->SelectedItem().SomeInt : 8
|
||||
) )
|
||||
{
|
||||
Msgbox::Alert(
|
||||
_("Error: The MemoryCard could not be created."),
|
||||
_("MemoryCard creation error")
|
||||
);
|
||||
return;
|
||||
}
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
|
||||
void Dialogs::CreateMemoryCardDialog::CreateControls()
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
m_check_CompressNTFS = new pxCheckBox( this,
|
||||
_("Use NTFS compression on this card"),
|
||||
@ -53,39 +148,26 @@ Dialogs::CreateMemoryCardDialog::CreateMemoryCardDialog( wxWindow* parent, uint
|
||||
);
|
||||
#endif
|
||||
|
||||
pxE( ".Dialog:Memorycards:NeedsFormatting",
|
||||
L"Your new MemoryCard needs to be formatted. Some games can format the card for you, while "
|
||||
L"others may require you do so using the BIOS. To boot into the BIOS, select the NoDisc option "
|
||||
L"as your CDVD Source."
|
||||
);
|
||||
|
||||
const RadioPanelItem tbl_CardSizes[] =
|
||||
{
|
||||
RadioPanelItem(_("8 MB [most compatible]"))
|
||||
. SetToolTip(_("8 meg carts are 'small' but are pretty well sure to work for any and all games.")),
|
||||
RadioPanelItem(_("8 MB [most compatible]"), _("This is the standard Sony-provisioned size, and is supported by all games and BIOS versions."))
|
||||
. SetToolTip(_("Always use this option if you want the safest and surest MemoryCard behavior."))
|
||||
. SetInt(8),
|
||||
|
||||
RadioPanelItem(_("16 MB"))
|
||||
. SetToolTip(_("16 and 32 MB cards have roughly the same compatibility factor. Most games see them fine, others may not.")),
|
||||
RadioPanelItem(_("16 MB"), _("A typical size for 3rd-party MemoryCards which should work with most games."))
|
||||
. SetToolTip(_("16 and 32 MB cards have roughly the same compatibility factor."))
|
||||
. SetInt(16),
|
||||
|
||||
RadioPanelItem(_("32 MB"))
|
||||
. SetToolTip(_("16 and 32 MB cards have roughly the same compatibility factor. Most games see them fine, others may not.")),
|
||||
RadioPanelItem(_("32 MB"), _("A typical size for 3rd-party MemoryCards which should work with most games."))
|
||||
. SetToolTip(_("16 and 32 MB cards have roughly the same compatibility factor."))
|
||||
. SetInt(32),
|
||||
|
||||
RadioPanelItem(_("64 MB"), _("Low compatibility! Use at your own risk."))
|
||||
. SetToolTip(_("Yes it's very big. Unfortunately a lot of games don't really work with them properly."))
|
||||
RadioPanelItem(_("64 MB"), _("Low compatibility warning: Yes it's very big, but may not work with many games."))
|
||||
. SetToolTip(_("Use at your own risk. Erratic memorycard behavior is possible (though unlikely)."))
|
||||
. SetInt(64)
|
||||
};
|
||||
|
||||
m_radio_CardSize = &(new pxRadioPanel( this, tbl_CardSizes ))->SetDefaultItem(0);
|
||||
|
||||
m_filepicker = CreateMemoryCardFilePicker( this, port, slot, filepath );
|
||||
|
||||
// ----------------------------
|
||||
// Sizers and Layout
|
||||
// ----------------------------
|
||||
|
||||
s_padding += m_filepicker | StdExpand();
|
||||
s_padding += m_radio_CardSize | StdExpand();
|
||||
|
||||
#ifdef __WXMSW__
|
||||
s_padding += m_check_CompressNTFS;
|
||||
#endif
|
||||
m_radio_CardSize = new pxRadioPanel( this, tbl_CardSizes );
|
||||
m_radio_CardSize->SetDefaultItem(0);
|
||||
}
|
||||
|
||||
|
@ -89,8 +89,8 @@ void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
|
||||
Panels::McdConfigPanel_Standard::McdConfigPanel_Standard(wxWindow *parent)
|
||||
: _parent( parent )
|
||||
{
|
||||
m_panel_cardinfo[0] = new MemoryCardInfoPanel( this, 0, 0 );
|
||||
m_panel_cardinfo[1] = new MemoryCardInfoPanel( this, 1, 0 );
|
||||
m_panel_cardinfo[0] = new MemoryCardInfoPanel( this, 0 );
|
||||
m_panel_cardinfo[1] = new MemoryCardInfoPanel( this, 1 );
|
||||
|
||||
for( uint port=0; port<2; ++port )
|
||||
{
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Utilities/SafeArray.h"
|
||||
|
||||
#include "MemoryCardFile.h"
|
||||
|
||||
// IMPORTANT! If this gets a macro redefinition error it means PluginCallbacks.h is included
|
||||
// in a global-scope header, and that's a BAD THING. Include it only into modules that need
|
||||
// it, because some need to be able to alter its behavior using defines. Like this:
|
||||
@ -32,8 +34,10 @@ struct Component_FileMcd;
|
||||
|
||||
#include <wx/ffile.h>
|
||||
|
||||
static const int MCD_SIZE = 1024 * 8 * 16; // Legacy PSX card default size
|
||||
static const int MC2_SIZE = 1024 * 528 * 16; // PS2 card default size.
|
||||
static const int MCD_SIZE = 1024 * 8 * 16; // Legacy PSX card default size
|
||||
|
||||
static const int MC2_MBSIZE = 1024 * 528 * 2; // Size of a single megabyte of card data
|
||||
static const int MC2_SIZE = MC2_SIZE * 8; // PS2 card default size (8MB)
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// FileMemoryCard
|
||||
@ -43,7 +47,7 @@ static const int MC2_SIZE = 1024 * 528 * 16; // PS2 card default size.
|
||||
class FileMemoryCard
|
||||
{
|
||||
protected:
|
||||
wxFFile m_file[2][4];
|
||||
wxFFile m_file[8];
|
||||
u8 m_effeffs[528*16];
|
||||
SafeArray<u8> m_currentdata;
|
||||
|
||||
@ -54,68 +58,116 @@ public:
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
s32 IsPresent( uint port, uint slot );
|
||||
s32 Read( uint port, uint slot, u8 *dest, u32 adr, int size );
|
||||
s32 Save( uint port, uint slot, const u8 *src, u32 adr, int size );
|
||||
s32 EraseBlock( uint port, uint slot, u32 adr );
|
||||
u64 GetCRC( uint port, uint slot );
|
||||
s32 IsPresent ( uint slot );
|
||||
s32 Read ( uint slot, u8 *dest, u32 adr, int size );
|
||||
s32 Save ( uint slot, const u8 *src, u32 adr, int size );
|
||||
s32 EraseBlock ( uint slot, u32 adr );
|
||||
u64 GetCRC ( uint slot );
|
||||
|
||||
protected:
|
||||
bool Seek( wxFFile& f, u32 adr );
|
||||
bool Create( const wxString& mcdFile );
|
||||
bool Create( const wxString& mcdFile, uint sizeInMB );
|
||||
|
||||
wxString GetDisabledMessage( uint port, uint slot ) const
|
||||
wxString GetDisabledMessage( uint slot ) const
|
||||
{
|
||||
return pxE( ".Popup:MemoryCard:HasBeenDisabled", wxsFormat(
|
||||
L"The MemoryCard in port %d/slot %d has been automatically disabled. You can correct the problem\n"
|
||||
L"The MemoryCard in slot %d has been automatically disabled. You can correct the problem\n"
|
||||
L"and re-enable the MemoryCard at any time using Config:MemoryCards from the main menu.",
|
||||
port, slot
|
||||
slot
|
||||
) );
|
||||
}
|
||||
};
|
||||
|
||||
uint FileMcd_GetMtapPort(uint slot)
|
||||
{
|
||||
switch( slot )
|
||||
{
|
||||
case 0: case 2: case 3: case 4: return 0;
|
||||
case 1: case 5: case 6: case 7: return 1;
|
||||
|
||||
jNO_DEFAULT
|
||||
}
|
||||
|
||||
return 0; // technically unreachable.
|
||||
}
|
||||
|
||||
uint FileMcd_GetMtapSlot(uint slot)
|
||||
{
|
||||
switch( slot )
|
||||
{
|
||||
case 0: case 1:
|
||||
pxFailDev( "Invalid parameter in call to GetMtapSlot -- specified slot is one of the base slots, not a Multitap slot." );
|
||||
break;
|
||||
|
||||
case 2: case 3: case 4: return 0;
|
||||
case 5: case 6: case 7: return 1;
|
||||
|
||||
jNO_DEFAULT
|
||||
}
|
||||
|
||||
return 0; // technically unreachable.
|
||||
}
|
||||
|
||||
bool FileMcd_IsMultitapSlot( uint slot )
|
||||
{
|
||||
return (slot > 1);
|
||||
}
|
||||
|
||||
wxFileName FileMcd_GetSimpleName(uint slot)
|
||||
{
|
||||
if( FileMcd_IsMultitapSlot(slot) )
|
||||
return g_Conf->Folders.MemoryCards + wxsFormat( L"Mcd-Multitap%u-Slot%02u.ps2", FileMcd_GetMtapPort(slot)+1, FileMcd_GetMtapSlot(slot)+1 );
|
||||
else
|
||||
return g_Conf->Folders.MemoryCards + wxsFormat( L"Mcd%03u.ps2", slot+1 );
|
||||
}
|
||||
|
||||
wxString FileMcd_GetDefaultName(uint slot)
|
||||
{
|
||||
if( FileMcd_IsMultitapSlot(slot) )
|
||||
return wxsFormat( L"Mcd-Multitap%u-Slot%02u.ps2", FileMcd_GetMtapPort(slot)+1, FileMcd_GetMtapSlot(slot)+1 );
|
||||
else
|
||||
return wxsFormat( L"Mcd%03u.ps2", slot+1 );
|
||||
}
|
||||
|
||||
FileMemoryCard::FileMemoryCard()
|
||||
{
|
||||
memset8<0xff>( m_effeffs );
|
||||
|
||||
for( int port=0; port<2; ++port )
|
||||
for( int slot=0; slot<8; ++slot )
|
||||
{
|
||||
for( int slot=0; slot<4; ++slot )
|
||||
if( !g_Conf->Mcd[slot].Enabled || g_Conf->Mcd[slot].Filename.GetFullName().IsEmpty() ) continue;
|
||||
|
||||
wxFileName fname( g_Conf->FullpathToMcd( slot ) );
|
||||
wxString str( fname.GetFullPath() );
|
||||
|
||||
const wxULongLong fsz = fname.GetSize();
|
||||
if( (fsz == 0) || (fsz == wxInvalidSize) )
|
||||
{
|
||||
if( !g_Conf->Mcd[port][slot].Enabled || g_Conf->Mcd[port][slot].Filename.GetFullName().IsEmpty() ) continue;
|
||||
|
||||
wxFileName fname( g_Conf->FullpathToMcd( port, slot ) );
|
||||
wxString str( fname.GetFullPath() );
|
||||
|
||||
const wxULongLong fsz = fname.GetSize();
|
||||
if( (fsz == 0) || (fsz == wxInvalidSize) )
|
||||
if( !Create( str, 8 ) )
|
||||
{
|
||||
if( !Create( str ) )
|
||||
{
|
||||
Msgbox::Alert(
|
||||
wxsFormat( _( "Could not create a MemoryCard file: \n\n%s\n\n" ), str.c_str() ) +
|
||||
GetDisabledMessage( port, slot )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// [TODO] : Add memcard size detection and report it to the console log.
|
||||
// (8MB, 256Mb, whatever)
|
||||
|
||||
#ifdef __WXMSW__
|
||||
NTFS_CompressFile( str, g_Conf->McdCompressNTFS );
|
||||
#endif
|
||||
|
||||
if( !m_file[port][slot].Open( str.c_str(), L"r+b" ) )
|
||||
{
|
||||
// Translation note: detailed description should mention that the memory card will be disabled
|
||||
// for the duration of this session.
|
||||
Msgbox::Alert(
|
||||
wxsFormat( _( "Access denied to MemoryCard file: \n\n%s\n\n" ), str.c_str() ) +
|
||||
GetDisabledMessage( port, slot )
|
||||
wxsFormat(_( "Could not create a MemoryCard file: \n\n%s\n\n" ), str.c_str()) +
|
||||
GetDisabledMessage( slot )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// [TODO] : Add memcard size detection and report it to the console log.
|
||||
// (8MB, 256Mb, whatever)
|
||||
|
||||
#ifdef __WXMSW__
|
||||
NTFS_CompressFile( str, g_Conf->McdCompressNTFS );
|
||||
#endif
|
||||
|
||||
if( !m_file[slot].Open( str.c_str(), L"r+b" ) )
|
||||
{
|
||||
// Translation note: detailed description should mention that the memory card will be disabled
|
||||
// for the duration of this session.
|
||||
Msgbox::Alert(
|
||||
wxsFormat(_( "Access denied to MemoryCard file: \n\n%s\n\n" ), str.c_str()) +
|
||||
GetDisabledMessage( slot )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,14 +195,16 @@ bool FileMemoryCard::Seek( wxFFile& f, u32 adr )
|
||||
}
|
||||
|
||||
// returns FALSE if an error occurred (either permission denied or disk full)
|
||||
bool FileMemoryCard::Create( const wxString& mcdFile )
|
||||
bool FileMemoryCard::Create( const wxString& mcdFile, uint sizeInMB )
|
||||
{
|
||||
//int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0};
|
||||
|
||||
Console.WriteLn( L"(FileMcd) Creating new %uMB MemoryCard: " + mcdFile, sizeInMB );
|
||||
|
||||
wxFFile fp( mcdFile, L"wb" );
|
||||
if( !fp.IsOpened() ) return false;
|
||||
|
||||
for( uint i=0; i<MC2_SIZE/sizeof(m_effeffs); i++ )
|
||||
for( uint i=0; i<(MC2_MBSIZE*sizeInMB)/sizeof(m_effeffs); i++ )
|
||||
{
|
||||
if( fp.Write( m_effeffs, sizeof(m_effeffs) ) == 0 )
|
||||
return false;
|
||||
@ -158,14 +212,14 @@ bool FileMemoryCard::Create( const wxString& mcdFile )
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 FileMemoryCard::IsPresent( uint port, uint slot )
|
||||
s32 FileMemoryCard::IsPresent( uint slot )
|
||||
{
|
||||
return m_file[port][slot].IsOpened();
|
||||
return m_file[slot].IsOpened();
|
||||
}
|
||||
|
||||
s32 FileMemoryCard::Read( uint port, uint slot, u8 *dest, u32 adr, int size )
|
||||
s32 FileMemoryCard::Read( uint slot, u8 *dest, u32 adr, int size )
|
||||
{
|
||||
wxFFile& mcfp( m_file[port][slot] );
|
||||
wxFFile& mcfp( m_file[slot] );
|
||||
if( !mcfp.IsOpened() )
|
||||
{
|
||||
DevCon.Error( "MemoryCard: Ignoring attempted read from disabled card." );
|
||||
@ -176,9 +230,9 @@ s32 FileMemoryCard::Read( uint port, uint slot, u8 *dest, u32 adr, int size )
|
||||
return mcfp.Read( dest, size ) != 0;
|
||||
}
|
||||
|
||||
s32 FileMemoryCard::Save( uint port, uint slot, const u8 *src, u32 adr, int size )
|
||||
s32 FileMemoryCard::Save( uint slot, const u8 *src, u32 adr, int size )
|
||||
{
|
||||
wxFFile& mcfp( m_file[port][slot] );
|
||||
wxFFile& mcfp( m_file[slot] );
|
||||
|
||||
if( !mcfp.IsOpened() )
|
||||
{
|
||||
@ -201,9 +255,9 @@ s32 FileMemoryCard::Save( uint port, uint slot, const u8 *src, u32 adr, int size
|
||||
return mcfp.Write( m_currentdata.GetPtr(), size ) != 0;
|
||||
}
|
||||
|
||||
s32 FileMemoryCard::EraseBlock( uint port, uint slot, u32 adr )
|
||||
s32 FileMemoryCard::EraseBlock( uint slot, u32 adr )
|
||||
{
|
||||
wxFFile& mcfp( m_file[port][slot] );
|
||||
wxFFile& mcfp( m_file[slot] );
|
||||
|
||||
if( !mcfp.IsOpened() )
|
||||
{
|
||||
@ -215,9 +269,9 @@ s32 FileMemoryCard::EraseBlock( uint port, uint slot, u32 adr )
|
||||
return mcfp.Write( m_effeffs, sizeof(m_effeffs) ) != 0;
|
||||
}
|
||||
|
||||
u64 FileMemoryCard::GetCRC( uint port, uint slot )
|
||||
u64 FileMemoryCard::GetCRC( uint slot )
|
||||
{
|
||||
wxFFile& mcfp( m_file[port][slot] );
|
||||
wxFFile& mcfp( m_file[slot] );
|
||||
if( !mcfp.IsOpened() ) return 0;
|
||||
|
||||
if( !Seek( mcfp, 0 ) ) return 0;
|
||||
@ -247,29 +301,36 @@ struct Component_FileMcd
|
||||
Component_FileMcd();
|
||||
};
|
||||
|
||||
uint FileMcd_ConvertToSlot( uint port, uint slot )
|
||||
{
|
||||
if( slot == 0 ) return port;
|
||||
if( port == 0 ) return slot+1; // multitap 1
|
||||
return slot + 4; // multitap 2
|
||||
}
|
||||
|
||||
static s32 PS2E_CALLBACK FileMcd_IsPresent( PS2E_THISPTR thisptr, uint port, uint slot )
|
||||
{
|
||||
return thisptr->impl.IsPresent( port, slot );
|
||||
return thisptr->impl.IsPresent( FileMcd_ConvertToSlot( port, slot ) );
|
||||
}
|
||||
|
||||
static s32 PS2E_CALLBACK FileMcd_Read( PS2E_THISPTR thisptr, uint port, uint slot, u8 *dest, u32 adr, int size )
|
||||
{
|
||||
return thisptr->impl.Read( port, slot, dest, adr, size );
|
||||
return thisptr->impl.Read( FileMcd_ConvertToSlot( port, slot ), dest, adr, 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( port, slot, src, adr, size );
|
||||
return thisptr->impl.Save( FileMcd_ConvertToSlot( port, slot ), src, adr, size );
|
||||
}
|
||||
|
||||
static s32 PS2E_CALLBACK FileMcd_EraseBlock( PS2E_THISPTR thisptr, uint port, uint slot, u32 adr )
|
||||
{
|
||||
return thisptr->impl.EraseBlock( port, slot, adr );
|
||||
return thisptr->impl.EraseBlock( FileMcd_ConvertToSlot( port, slot ), adr );
|
||||
}
|
||||
|
||||
static u64 PS2E_CALLBACK FileMcd_GetCRC( PS2E_THISPTR thisptr, uint port, uint slot )
|
||||
{
|
||||
return thisptr->impl.GetCRC( port, slot );
|
||||
return thisptr->impl.GetCRC( FileMcd_ConvertToSlot( port, slot ) );
|
||||
}
|
||||
|
||||
Component_FileMcd::Component_FileMcd()
|
||||
@ -354,8 +415,9 @@ extern "C" const PS2E_LibraryAPI* FileMcd_InitAPI( const PS2E_EmulatorInfo* emui
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Currently Unused Superblock Header Structs
|
||||
// Currently Unused Superblock Header Struct
|
||||
// --------------------------------------------------------------------------------------
|
||||
// (provided for reference purposes)
|
||||
|
||||
struct superblock
|
||||
{
|
||||
@ -376,17 +438,3 @@ struct superblock
|
||||
u8 card_type; // 0x150
|
||||
u8 card_flags; // 0x151
|
||||
};
|
||||
|
||||
#if 0 // unused code?
|
||||
struct McdBlock
|
||||
{
|
||||
s8 Title[48];
|
||||
s8 ID[14];
|
||||
s8 Name[16];
|
||||
int IconCount;
|
||||
u16 Icon[16*16*3];
|
||||
u8 Flags;
|
||||
};
|
||||
|
||||
void GetMcdBlockInfo(int mcd, int block, McdBlock *info);
|
||||
#endif
|
||||
|
29
pcsx2/gui/MemoryCardFile.h
Normal file
29
pcsx2/gui/MemoryCardFile.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 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-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// 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).
|
||||
//
|
||||
// Please do not move contents from MemoryCardfile.cpp, such as class definitions, into
|
||||
// this file. I'd prefer they stay in MemoryCardFile.cpp for now. --air
|
||||
|
||||
extern uint FileMcd_GetMtapPort(uint slot);
|
||||
extern uint FileMcd_GetMtapSlot(uint slot);
|
||||
extern bool FileMcd_IsMultitapSlot( uint slot );
|
||||
extern wxFileName FileMcd_GetSimpleName(uint slot);
|
||||
extern wxString FileMcd_GetDefaultName(uint slot);
|
@ -172,9 +172,7 @@ namespace Msgbox
|
||||
// Always returns false.
|
||||
bool Alert( const wxString& text, const wxString& caption, int icon )
|
||||
{
|
||||
MsgButtons buttons( MsgButtons().OK() );
|
||||
|
||||
ShowModal( caption, text, buttons );
|
||||
ShowModal( caption, text, MsgButtons().OK() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -61,12 +61,17 @@ bool Panels::BaseSelectorPanel::Show( bool visible )
|
||||
return BaseApplicableConfigPanel::Show( visible );
|
||||
}
|
||||
|
||||
void Panels::BaseSelectorPanel::OnRefresh( wxCommandEvent& evt )
|
||||
void Panels::BaseSelectorPanel::RefreshSelections()
|
||||
{
|
||||
ValidateEnumerationStatus();
|
||||
DoRefresh();
|
||||
}
|
||||
|
||||
void Panels::BaseSelectorPanel::OnRefreshSelections( wxCommandEvent& evt )
|
||||
{
|
||||
RefreshSelections();
|
||||
}
|
||||
|
||||
void Panels::BaseSelectorPanel::OnFolderChanged( wxFileDirPickerEvent& evt )
|
||||
{
|
||||
evt.Skip();
|
||||
@ -100,7 +105,7 @@ Panels::BiosSelectorPanel::BiosSelectorPanel( wxWindow* parent, int idealWidth )
|
||||
*this += 8;
|
||||
*this += m_FolderPicker | StdExpand();
|
||||
|
||||
Connect( refreshButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BaseSelectorPanel::OnRefresh) );
|
||||
Connect( refreshButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BiosSelectorPanel::OnRefreshSelections) );
|
||||
}
|
||||
|
||||
Panels::BiosSelectorPanel::~BiosSelectorPanel() throw ()
|
||||
|
@ -378,12 +378,15 @@ namespace Panels
|
||||
virtual ~BaseSelectorPanel() throw();
|
||||
BaseSelectorPanel( wxWindow* parent );
|
||||
|
||||
virtual void RefreshSelections();
|
||||
|
||||
virtual bool Show( bool visible=true );
|
||||
virtual void OnRefresh( wxCommandEvent& evt );
|
||||
virtual void OnShown();
|
||||
virtual void OnFolderChanged( wxFileDirPickerEvent& evt );
|
||||
|
||||
protected:
|
||||
void OnRefreshSelections( wxCommandEvent& evt );
|
||||
|
||||
virtual void DoRefresh()=0;
|
||||
virtual bool ValidateEnumerationStatus()=0;
|
||||
void OnShow(wxShowEvent& evt);
|
||||
@ -420,11 +423,11 @@ namespace Panels
|
||||
{
|
||||
protected:
|
||||
MemoryCardListPanel_Advanced* m_panel_AllKnownCards;
|
||||
MemoryCardInfoPanel* m_panel_cardinfo[2][4];
|
||||
MemoryCardInfoPanel* m_panel_cardinfo[8];
|
||||
pxCheckBox* m_check_Ejection;
|
||||
pxCheckBox* m_check_Multitap[2];
|
||||
|
||||
uint m_Bindings[2][4];
|
||||
uint m_Bindings[8];
|
||||
|
||||
public:
|
||||
MemoryCardsPanel( wxWindow* parent );
|
||||
|
@ -16,10 +16,14 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ConfigurationPanels.h"
|
||||
#include "MemoryCardPanels.h"
|
||||
#include "System.h"
|
||||
|
||||
#include <wx/filepicker.h>
|
||||
#include <wx/ffile.h>
|
||||
#include <wx/dir.h>
|
||||
#include "Dialogs/ConfigurationDialog.h"
|
||||
|
||||
#include "MemoryCardFile.h"
|
||||
|
||||
|
||||
using namespace pxSizerFlags;
|
||||
@ -86,6 +90,48 @@ static int EnumerateMemoryCards( McdList& dest, const wxArrayString& files )
|
||||
return pushed;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// McdListItem (implementations)
|
||||
// --------------------------------------------------------------------------------------
|
||||
bool McdListItem::IsMultitapSlot() const
|
||||
{
|
||||
return FileMcd_IsMultitapSlot(Slot);
|
||||
}
|
||||
|
||||
uint McdListItem::GetMtapPort() const
|
||||
{
|
||||
return FileMcd_GetMtapPort(Slot);
|
||||
}
|
||||
|
||||
uint McdListItem::GetMtapSlot() const
|
||||
{
|
||||
return FileMcd_GetMtapSlot(Slot);
|
||||
}
|
||||
|
||||
// Compares two cards -- If this equality comparison is used on items where
|
||||
// no filename is specified, then the check will include port and slot.
|
||||
bool McdListItem::operator==( const McdListItem& right ) const
|
||||
{
|
||||
bool fileEqu;
|
||||
|
||||
if( Filename.GetFullName().IsEmpty() )
|
||||
fileEqu = OpEqu(Slot);
|
||||
else
|
||||
fileEqu = OpEqu(Filename);
|
||||
|
||||
return fileEqu &&
|
||||
OpEqu(IsPresent) && OpEqu(IsEnabled) &&
|
||||
OpEqu(SizeInMB) && OpEqu(IsFormatted) &&
|
||||
OpEqu(DateCreated) && OpEqu(DateModified);
|
||||
}
|
||||
|
||||
bool McdListItem::operator!=( const McdListItem& right ) const
|
||||
{
|
||||
return operator==( right );
|
||||
}
|
||||
|
||||
//DEFINE_EVENT_TYPE( pxEvt_RefreshSelections );
|
||||
|
||||
// =====================================================================================================
|
||||
// BaseMcdListPanel (implementations)
|
||||
// =====================================================================================================
|
||||
@ -101,9 +147,23 @@ Panels::BaseMcdListPanel::BaseMcdListPanel( wxWindow* parent )
|
||||
|
||||
m_btn_Refresh = new wxButton( this, wxID_ANY, _("Refresh list") );
|
||||
|
||||
Connect( m_btn_Refresh->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BaseMcdListPanel::OnRefresh) );
|
||||
Connect( m_btn_Refresh->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BaseMcdListPanel::OnRefreshSelections) );
|
||||
//Connect( pxEvt_RefreshSelections, wxCommandEventHandler(BaseMcdListPanel::OnRefreshSelections) );
|
||||
}
|
||||
|
||||
void Panels::BaseMcdListPanel::RefreshMcds() const
|
||||
{
|
||||
wxCommandEvent refit( wxEVT_COMMAND_BUTTON_CLICKED );
|
||||
refit.SetId( m_btn_Refresh->GetId() );
|
||||
GetEventHandler()->AddPendingEvent( refit );
|
||||
}
|
||||
|
||||
/*void Panels::BaseMcdListPanel::OnEvent_McdRefresh( wxCommandEvent& evt ) const
|
||||
{
|
||||
RefreshSelections();
|
||||
evt.Skip();
|
||||
}*/
|
||||
|
||||
void Panels::BaseMcdListPanel::CreateLayout()
|
||||
{
|
||||
if( m_listview ) m_listview->SetMinSize( wxSize( m_idealWidth, 140 ) );
|
||||
@ -145,8 +205,8 @@ Panels::MemoryCardListPanel_Advanced::MemoryCardListPanel_Advanced( wxWindow* pa
|
||||
CreateLayout();
|
||||
*s_leftside_buttons += button_Create | StdSpace();
|
||||
|
||||
Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel_Advanced::OnListDrag));
|
||||
Connect( button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Advanced::OnCreateNewCard));
|
||||
Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler (MemoryCardListPanel_Advanced::OnListDrag));
|
||||
Connect( button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (MemoryCardListPanel_Advanced::OnCreateNewCard));
|
||||
}
|
||||
|
||||
void Panels::MemoryCardListPanel_Advanced::Apply()
|
||||
@ -185,7 +245,7 @@ bool Panels::MemoryCardListPanel_Advanced::ValidateEnumerationStatus()
|
||||
if( !m_KnownCards || (*mcdlist != *m_KnownCards) )
|
||||
validated = false;
|
||||
|
||||
m_listview->SetInterface( NULL );
|
||||
m_listview->SetMcdProvider( NULL );
|
||||
m_KnownCards.SwapPtr( mcdlist );
|
||||
|
||||
return validated;
|
||||
@ -199,10 +259,9 @@ void Panels::MemoryCardListPanel_Advanced::DoRefresh()
|
||||
{
|
||||
McdListItem& mcditem( (*m_KnownCards)[i] );
|
||||
|
||||
for( int port=0; port<2; ++port )
|
||||
for( int slot=0; slot<4; ++slot )
|
||||
for( int slot=0; slot<8; ++slot )
|
||||
{
|
||||
wxFileName right( g_Conf->FullpathToMcd(port, slot) );
|
||||
wxFileName right( g_Conf->FullpathToMcd(slot) );
|
||||
right.MakeAbsolute();
|
||||
|
||||
wxFileName left( mcditem.Filename );
|
||||
@ -210,13 +269,12 @@ void Panels::MemoryCardListPanel_Advanced::DoRefresh()
|
||||
|
||||
if( left == right )
|
||||
{
|
||||
mcditem.Port = port;
|
||||
mcditem.Slot = slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_listview->SetInterface( this );
|
||||
m_listview->SetMcdProvider( this );
|
||||
//m_listview->SetCardCount( m_KnownCards->size() );
|
||||
}
|
||||
|
||||
@ -232,7 +290,7 @@ void Panels::MemoryCardListPanel_Advanced::OnListDrag(wxListEvent& evt)
|
||||
|
||||
wxDropSource dragSource( m_listview );
|
||||
dragSource.SetData( my_data );
|
||||
wxDragResult result = dragSource.DoDragDrop();
|
||||
wxDragResult result = dragSource.DoDragDrop(wxDrag_AllowMove);
|
||||
}
|
||||
|
||||
int Panels::MemoryCardListPanel_Advanced::GetLength() const
|
||||
@ -252,17 +310,223 @@ McdListItem& Panels::MemoryCardListPanel_Advanced::GetCard( int idx )
|
||||
return (*m_KnownCards)[idx];
|
||||
}
|
||||
|
||||
uint Panels::MemoryCardListPanel_Advanced::GetPort( int idx ) const
|
||||
// --------------------------------------------------------------------------------------
|
||||
// McdDataObject
|
||||
// --------------------------------------------------------------------------------------
|
||||
class WXDLLEXPORT McdDataObject : public wxDataObjectSimple
|
||||
{
|
||||
pxAssume(!!m_KnownCards);
|
||||
return (*m_KnownCards)[idx].Port;
|
||||
}
|
||||
DECLARE_NO_COPY_CLASS(McdDataObject)
|
||||
|
||||
uint Panels::MemoryCardListPanel_Advanced::GetSlot( int idx ) const
|
||||
protected:
|
||||
int m_slot;
|
||||
|
||||
public:
|
||||
McdDataObject(int slot = -1)
|
||||
: wxDataObjectSimple( wxDF_PRIVATE )
|
||||
{
|
||||
m_slot = slot;
|
||||
}
|
||||
|
||||
uint GetSlot() const
|
||||
{
|
||||
pxAssumeDev( m_slot >= 0, "Memorycard Index is uninitialized (invalid drag&drop object state)" );
|
||||
return (uint)m_slot;
|
||||
}
|
||||
|
||||
size_t GetDataSize() const
|
||||
{
|
||||
return sizeof(u32);
|
||||
}
|
||||
|
||||
bool GetDataHere(void *buf) const
|
||||
{
|
||||
*(u32*)buf = GetSlot();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool SetData(size_t len, const void *buf)
|
||||
{
|
||||
if( !pxAssertDev( len == sizeof(u32), "Data length mismatch on memorycard drag&drop operation." ) ) return false;
|
||||
|
||||
m_slot = *(u32*)buf;
|
||||
return ( (uint)m_slot < 8 ); // sanity check (unsigned, so that -1 also is invalid) :)
|
||||
}
|
||||
|
||||
// Must provide overloads to avoid hiding them (and warnings about it)
|
||||
virtual size_t GetDataSize(const wxDataFormat&) const
|
||||
{
|
||||
return GetDataSize();
|
||||
}
|
||||
|
||||
virtual bool GetDataHere(const wxDataFormat&, void *buf) const
|
||||
{
|
||||
return GetDataHere(buf);
|
||||
}
|
||||
|
||||
virtual bool SetData(const wxDataFormat&, size_t len, const void *buf)
|
||||
{
|
||||
return SetData(len, buf);
|
||||
}
|
||||
};
|
||||
|
||||
class McdDropTarget : public wxDropTarget
|
||||
{
|
||||
pxAssume(!!m_KnownCards);
|
||||
return (*m_KnownCards)[idx].Slot;
|
||||
}
|
||||
protected:
|
||||
BaseMcdListView* m_listview;
|
||||
|
||||
public:
|
||||
McdDropTarget( BaseMcdListView* listview=NULL )
|
||||
{
|
||||
m_listview = listview;
|
||||
SetDataObject(new McdDataObject());
|
||||
}
|
||||
|
||||
// these functions are called when data is moved over position (x, y) and
|
||||
// may return either wxDragCopy, wxDragMove or wxDragNone depending on
|
||||
// what would happen if the data were dropped here.
|
||||
//
|
||||
// the last parameter is what would happen by default and is determined by
|
||||
// the platform-specific logic (for example, under Windows it's wxDragCopy
|
||||
// if Ctrl key is pressed and wxDragMove otherwise) except that it will
|
||||
// always be wxDragNone if the carried data is in an unsupported format.
|
||||
|
||||
|
||||
// called when the mouse moves in the window - shouldn't take long to
|
||||
// execute or otherwise mouse movement would be too slow.
|
||||
virtual wxDragResult OnDragOver(wxCoord x, wxCoord y, wxDragResult def)
|
||||
{
|
||||
int flags = 0;
|
||||
int idx = m_listview->HitTest( wxPoint(x,y), flags);
|
||||
m_listview->SetTargetedItem( idx );
|
||||
|
||||
if( wxNOT_FOUND == idx ) return wxDragNone;
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
virtual void OnLeave()
|
||||
{
|
||||
m_listview->SetTargetedItem( wxNOT_FOUND );
|
||||
}
|
||||
|
||||
// this function is called when data is dropped at position (x, y) - if it
|
||||
// returns true, OnData() will be called immediately afterwards which will
|
||||
// allow to retrieve the data dropped.
|
||||
virtual bool OnDrop(wxCoord x, wxCoord y)
|
||||
{
|
||||
int flags = 0;
|
||||
int idx = m_listview->HitTest( wxPoint(x,y), flags);
|
||||
return ( wxNOT_FOUND != idx );
|
||||
}
|
||||
|
||||
// may be called *only* from inside OnData() and will fill m_dataObject
|
||||
// with the data from the drop source if it returns true
|
||||
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def)
|
||||
{
|
||||
m_listview->SetTargetedItem( wxNOT_FOUND );
|
||||
|
||||
int flags = 0;
|
||||
int idx = m_listview->HitTest( wxPoint(x,y), flags);
|
||||
if( wxNOT_FOUND == idx ) return wxDragNone;
|
||||
|
||||
if ( !GetData() ) return wxDragNone;
|
||||
|
||||
McdDataObject *dobj = (McdDataObject *)m_dataObject;
|
||||
|
||||
wxDragResult result = OnDropMcd(
|
||||
m_listview->GetMcdProvider().GetCard(dobj->GetSlot()),
|
||||
m_listview->GetMcdProvider().GetCard(idx),
|
||||
def
|
||||
);
|
||||
|
||||
if( wxDragNone == result ) return wxDragNone;
|
||||
m_listview->GetMcdProvider().RefreshMcds();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual wxDragResult OnDropMcd( const McdListItem& src, const McdListItem& dest, wxDragResult def )
|
||||
{
|
||||
if( src.Slot == dest.Slot ) return wxDragNone;
|
||||
if( !pxAssert( (src.Slot >= 0) && (dest.Slot >= 0) ) ) return wxDragNone;
|
||||
|
||||
const wxDirName basepath( m_listview->GetMcdProvider().GetMcdPath() );
|
||||
wxFileName srcfile( basepath + g_Conf->Mcd[src.Slot].Filename );
|
||||
wxFileName destfile( basepath + g_Conf->Mcd[dest.Slot].Filename );
|
||||
|
||||
if( wxDragCopy == def )
|
||||
{
|
||||
// user is force invoking copy mode, which means we need to check the destination
|
||||
// and prompt if it looks valuable (formatted).
|
||||
|
||||
if( dest.IsPresent && dest.IsFormatted )
|
||||
{
|
||||
wxsFormat( pxE( ".Popup:Mcd:Overwrite",
|
||||
L"This will copy the contents of the MemoryCard in slot %u over the Memorycard in slot %u. "
|
||||
L"All data on the target slot will be lost. Are you sure?" ),
|
||||
src.Slot, dest.Slot
|
||||
);
|
||||
|
||||
//if( !Msgbox::OkCancel( ) )
|
||||
// return wxDragNone;
|
||||
}
|
||||
|
||||
ScopedBusyCursor doh( Cursor_ReallyBusy );
|
||||
if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
|
||||
{
|
||||
wxString heading;
|
||||
heading.Printf( pxE( ".Error:Mcd:Copy Failed",
|
||||
L"Error! Could not copy the MemoryCard into slot %u. The destination file is in use." ),
|
||||
dest.Slot
|
||||
);
|
||||
|
||||
wxString content;
|
||||
|
||||
Msgbox::Alert( heading + L"\n\n" + content, _("Copy failed!") );
|
||||
return wxDragNone;
|
||||
}
|
||||
}
|
||||
else if( wxDragMove == def )
|
||||
{
|
||||
// Move always performs a swap :)
|
||||
|
||||
const bool srcExists( srcfile.FileExists() );
|
||||
const bool destExists( destfile.FileExists() );
|
||||
|
||||
bool result = true;
|
||||
|
||||
if( destExists && srcExists)
|
||||
{
|
||||
wxFileName tempname;
|
||||
tempname.AssignTempFileName( basepath.ToString() );
|
||||
|
||||
// Neat trick to handle errors.
|
||||
result = result && wxRenameFile( srcfile.GetFullPath(), tempname.GetFullPath(), true );
|
||||
result = result && wxRenameFile( destfile.GetFullPath(), srcfile.GetFullPath(), false );
|
||||
result = result && wxRenameFile( tempname.GetFullPath(), srcfile.GetFullPath(), true );
|
||||
}
|
||||
else if( destExists )
|
||||
{
|
||||
result = wxRenameFile( destfile.GetFullPath(), srcfile.GetFullPath() );
|
||||
}
|
||||
else if( srcExists )
|
||||
{
|
||||
result = wxRenameFile( srcfile.GetFullPath(), destfile.GetFullPath() );
|
||||
}
|
||||
|
||||
if( !result )
|
||||
{
|
||||
// TODO : Popup an error to the user.
|
||||
|
||||
Console.Error( "(McdFile) Memorycard swap failed." );
|
||||
Console.Indent().WriteLn( L"Src : " + srcfile.GetFullPath() );
|
||||
Console.Indent().WriteLn( L"Dest: " + destfile.GetFullPath() );
|
||||
}
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
};
|
||||
|
||||
// =====================================================================================================
|
||||
// MemoryCardListPanel_Simple (implementations)
|
||||
@ -274,6 +538,7 @@ Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent
|
||||
m_MultitapEnabled[1] = false;
|
||||
|
||||
m_listview = new MemoryCardListView_Simple(this);
|
||||
m_listview->SetDropTarget( new McdDropTarget(m_listview) );
|
||||
|
||||
m_button_Create = new wxButton(this, wxID_ANY, _("Create"));
|
||||
m_button_Mount = new wxButton(this, wxID_ANY, _("Mount"));
|
||||
@ -291,7 +556,7 @@ Panels::MemoryCardListPanel_Simple::MemoryCardListPanel_Simple( wxWindow* parent
|
||||
|
||||
Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel_Simple::OnListDrag));
|
||||
Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(MemoryCardListPanel_Simple::OnListSelectionChanged));
|
||||
Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(MemoryCardListPanel_Simple::OnListSelectionChanged));
|
||||
Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_ITEM_DESELECTED, wxListEventHandler(MemoryCardListPanel_Simple::OnListSelectionChanged));
|
||||
|
||||
Connect( m_button_Mount->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnMountCard));
|
||||
Connect( m_button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel_Simple::OnCreateCard));
|
||||
@ -303,6 +568,13 @@ void Panels::MemoryCardListPanel_Simple::UpdateUI()
|
||||
|
||||
int sel = m_listview->GetFirstSelected();
|
||||
|
||||
if( wxNOT_FOUND == sel )
|
||||
{
|
||||
m_button_Create->Disable();
|
||||
m_button_Mount->Disable();
|
||||
return;
|
||||
}
|
||||
|
||||
/*if( !pxAssertDev( m_listview->GetItemData(sel), "Selected memorycard item data is NULL!" ) )
|
||||
{
|
||||
m_button_Create->Disable();
|
||||
@ -310,9 +582,9 @@ void Panels::MemoryCardListPanel_Simple::UpdateUI()
|
||||
return;
|
||||
}*/
|
||||
|
||||
//const McdListItem& item( *(McdListItem*)m_listview->GetItemData(sel) );
|
||||
const McdListItem& item( m_Cards[GetPort(sel)][GetSlot(sel)] );
|
||||
const McdListItem& item( m_Cards[sel] );
|
||||
|
||||
m_button_Create->Enable();
|
||||
m_button_Create->SetLabel( item.IsPresent ? _("Delete") : _("Create") );
|
||||
pxSetToolTip( m_button_Create,
|
||||
item.IsPresent
|
||||
@ -348,55 +620,88 @@ bool Panels::MemoryCardListPanel_Simple::OnDropFiles(wxCoord x, wxCoord y, const
|
||||
return false;
|
||||
}
|
||||
|
||||
static wxString GetAutoMcdName(uint port, uint slot)
|
||||
{
|
||||
if( slot > 0 )
|
||||
return wxsFormat( L"mcd-port%u-slot%02u.ps2", port+1, slot+1 );
|
||||
else
|
||||
return wxsFormat( L"Mcd%03u.ps2", port+1 );
|
||||
}
|
||||
|
||||
bool Panels::MemoryCardListPanel_Simple::ValidateEnumerationStatus()
|
||||
{
|
||||
if( m_listview ) m_listview->SetInterface( NULL );
|
||||
if( m_listview ) m_listview->SetMcdProvider( NULL );
|
||||
return false;
|
||||
}
|
||||
|
||||
void Panels::MemoryCardListPanel_Simple::DoRefresh()
|
||||
{
|
||||
for( uint port=0; port<2; ++port )
|
||||
for( uint slot=0; slot<8; ++slot )
|
||||
{
|
||||
for( uint slot=0; slot<4; ++slot )
|
||||
{
|
||||
wxFileName fullpath( m_FolderPicker->GetPath() + GetAutoMcdName(port,slot) );
|
||||
EnumerateMemoryCard( m_Cards[port][slot], fullpath );
|
||||
wxFileName fullpath( m_FolderPicker->GetPath() + g_Conf->Mcd[slot].Filename.GetFullName() );
|
||||
EnumerateMemoryCard( m_Cards[slot], fullpath );
|
||||
|
||||
if( (slot > 0) && !m_MultitapEnabled[port] )
|
||||
m_Cards[port][slot].IsEnabled = false;
|
||||
}
|
||||
m_Cards[slot].Slot = slot;
|
||||
|
||||
if( FileMcd_IsMultitapSlot(slot) && !m_MultitapEnabled[FileMcd_GetMtapPort(slot)] )
|
||||
m_Cards[slot].IsEnabled = false;
|
||||
}
|
||||
|
||||
if( m_listview ) m_listview->SetInterface( this );
|
||||
if( m_listview ) m_listview->SetMcdProvider( this );
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
|
||||
{
|
||||
const int sel = m_listview->GetFirstSelected();
|
||||
if( wxNOT_FOUND == sel ) return;
|
||||
const uint slot = sel;
|
||||
|
||||
if( m_Cards[slot].IsPresent )
|
||||
{
|
||||
wxWindowID result = wxID_YES;
|
||||
if( m_Cards[slot].IsFormatted )
|
||||
{
|
||||
wxString content;
|
||||
content.Printf(wxsFormat(
|
||||
pxE(".Popup:DeleteMemoryCard",
|
||||
L"You are about to delete the formatted memory card in slot %u. "
|
||||
L"All data on this card will be lost! Are you absolutely and quite positively sure?"
|
||||
), slot )
|
||||
);
|
||||
|
||||
result = Msgbox::YesNo( content, _("Delete MemoryCard?") );
|
||||
}
|
||||
|
||||
if( result == wxID_YES )
|
||||
{
|
||||
wxFileName fullpath( m_FolderPicker->GetPath() + g_Conf->Mcd[slot].Filename.GetFullName() );
|
||||
wxRemoveFile( fullpath.GetFullPath() );
|
||||
}
|
||||
}
|
||||
else
|
||||
Dialogs::CreateMemoryCardDialog( this, slot, m_FolderPicker->GetPath() ).ShowModal();
|
||||
|
||||
RefreshSelections();
|
||||
}
|
||||
|
||||
/*void Panels::MemoryCardListPanel_Simple::OnSwapPorts(wxCommandEvent& evt)
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
void Panels::MemoryCardListPanel_Simple::OnMountCard(wxCommandEvent& evt)
|
||||
{
|
||||
const int sel = m_listview->GetFirstSelected();
|
||||
if( wxNOT_FOUND == sel ) return;
|
||||
const uint slot = sel;
|
||||
|
||||
m_Cards[slot].IsEnabled = !m_Cards[slot].IsEnabled;
|
||||
RefreshSelections();
|
||||
}
|
||||
|
||||
void Panels::MemoryCardListPanel_Simple::OnListDrag(wxListEvent& evt)
|
||||
{
|
||||
wxFileDataObject my_data;
|
||||
/*my_data.AddFile( (*m_KnownCards)[m_listview->GetItemData(m_listview->GetFirstSelected())].Filename.GetFullPath() );
|
||||
int selection = m_listview->GetFirstSelected();
|
||||
|
||||
if( selection < 0 ) return;
|
||||
McdDataObject my_data( selection );
|
||||
|
||||
wxDropSource dragSource( m_listview );
|
||||
dragSource.SetData( my_data );
|
||||
wxDragResult result = dragSource.DoDragDrop();*/
|
||||
wxDragResult result = dragSource.DoDragDrop( wxDrag_AllowMove );
|
||||
}
|
||||
|
||||
void Panels::MemoryCardListPanel_Simple::OnListSelectionChanged(wxListEvent& evt)
|
||||
@ -415,38 +720,10 @@ int Panels::MemoryCardListPanel_Simple::GetLength() const
|
||||
|
||||
const McdListItem& Panels::MemoryCardListPanel_Simple::GetCard( int idx ) const
|
||||
{
|
||||
return m_Cards[GetPort(idx)][GetSlot(idx)];
|
||||
return m_Cards[idx];
|
||||
}
|
||||
|
||||
McdListItem& Panels::MemoryCardListPanel_Simple::GetCard( int idx )
|
||||
{
|
||||
return m_Cards[GetPort(idx)][GetSlot(idx)];
|
||||
}
|
||||
|
||||
uint Panels::MemoryCardListPanel_Simple::GetPort( int idx ) const
|
||||
{
|
||||
if( !m_MultitapEnabled[0] && !m_MultitapEnabled[1] )
|
||||
{
|
||||
pxAssume( idx < 2 );
|
||||
return idx;
|
||||
}
|
||||
|
||||
if( !m_MultitapEnabled[0] )
|
||||
return (idx==0) ? 0 : 1;
|
||||
else
|
||||
return idx / 4;
|
||||
}
|
||||
|
||||
uint Panels::MemoryCardListPanel_Simple::GetSlot( int idx ) const
|
||||
{
|
||||
if( !m_MultitapEnabled[0] && !m_MultitapEnabled[1] )
|
||||
{
|
||||
pxAssume( idx < 2 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !m_MultitapEnabled[0] )
|
||||
return (idx==0) ? 0 : (idx-1);
|
||||
else
|
||||
return idx & 3;
|
||||
return m_Cards[idx];
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ MemoryCardListView_Simple::MemoryCardListView_Simple( wxWindow* parent )
|
||||
: _parent( parent )
|
||||
{
|
||||
CreateColumns();
|
||||
Connect( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListView_Advanced::OnListDrag));
|
||||
}
|
||||
|
||||
void MemoryCardListView_Simple::SetCardCount( int length )
|
||||
@ -69,11 +68,6 @@ void MemoryCardListView_Simple::SetCardCount( int length )
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void MemoryCardListView_Simple::OnListDrag(wxListEvent& evt)
|
||||
{
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
// return the text for the given column of the given item
|
||||
wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
|
||||
{
|
||||
@ -83,16 +77,15 @@ wxString MemoryCardListView_Simple::OnGetItemText(long item, long column) const
|
||||
|
||||
switch( column )
|
||||
{
|
||||
case McdColS_PortSlot: return wxsFormat( L"%u/%u", m_CardProvider->GetPort(item)+1, m_CardProvider->GetSlot(item)+1);
|
||||
case McdColS_PortSlot: return wxsFormat( L"%u", item+1);
|
||||
case McdColS_Status: return it.IsPresent ? ( it.IsEnabled ? _("Enabled") : _("Disabled")) : _("Missing");
|
||||
case McdColS_Size: return it.IsPresent ? wxsFormat( L"%u MB", it.SizeInMB ) : (wxString)_("N/A");
|
||||
case McdColS_Formatted: return it.IsFormatted ? _("Yes") : _("No");
|
||||
case McdColS_DateModified: return it.IsPresent ? it.DateModified.FormatDate() : (wxString)_("N/A");
|
||||
case McdColS_DateCreated: return it.IsPresent ? it.DateCreated.FormatDate() : (wxString)_("N/A");
|
||||
//case McdCol_Path: return it.Filename.GetPath();
|
||||
}
|
||||
|
||||
pxFail( "Unknown column index in MemoryCardListView_Advanced -- returning an empty string." );
|
||||
pxFail( "Unknown column index in MemoryCardListView -- returning an empty string." );
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
@ -110,10 +103,24 @@ int MemoryCardListView_Simple::OnGetItemColumnImage(long item, long column) cons
|
||||
return _parent::OnGetItemColumnImage( item, column );
|
||||
}
|
||||
|
||||
static wxListItemAttr m_ItemAttr;
|
||||
|
||||
// return the attribute for the item (may return NULL if none)
|
||||
wxListItemAttr* MemoryCardListView_Simple::OnGetItemAttr(long item) const
|
||||
{
|
||||
wxListItemAttr* retval = _parent::OnGetItemAttr(item);
|
||||
//const McdListItem& it( (*m_KnownCards)[item] );
|
||||
return retval;
|
||||
//m_disabled.SetTextColour( wxLIGHT_GREY );
|
||||
//m_targeted.SetBackgroundColour( wxColour(L"Yellow") );
|
||||
|
||||
if( !m_CardProvider ) return _parent::OnGetItemAttr(item);
|
||||
const McdListItem& it( m_CardProvider->GetCard(item) );
|
||||
|
||||
m_ItemAttr = wxListItemAttr(); // Wipe it clean!
|
||||
|
||||
if( !it.IsEnabled )
|
||||
m_ItemAttr.SetTextColour( *wxLIGHT_GREY );
|
||||
|
||||
if( m_TargetedItem == item )
|
||||
m_ItemAttr.SetBackgroundColour( wxColour(L"Wheat") );
|
||||
|
||||
return &m_ItemAttr;
|
||||
}
|
||||
|
@ -33,41 +33,25 @@ struct McdListItem
|
||||
wxDateTime DateCreated;
|
||||
wxDateTime DateModified;
|
||||
|
||||
int Port;
|
||||
int Slot;
|
||||
|
||||
wxFileName Filename; // full pathname (optional)
|
||||
|
||||
McdListItem()
|
||||
{
|
||||
Port = -1;
|
||||
Slot = -1;
|
||||
//Port = -1;
|
||||
Slot = -1;
|
||||
|
||||
IsPresent = false;
|
||||
IsEnabled = false;
|
||||
}
|
||||
|
||||
bool IsMultitapSlot() const;
|
||||
uint GetMtapPort() const;
|
||||
uint GetMtapSlot() const;
|
||||
|
||||
// Compares two cards -- If this equality comparison is used on items where
|
||||
// no filename is specified, then the check will include port and slot.
|
||||
bool operator==( const McdListItem& right ) const
|
||||
{
|
||||
bool fileEqu;
|
||||
|
||||
if( Filename.GetFullName().IsEmpty() )
|
||||
fileEqu = OpEqu(Port) && OpEqu(Slot);
|
||||
else
|
||||
fileEqu = OpEqu(Filename);
|
||||
|
||||
return fileEqu &&
|
||||
OpEqu(IsPresent) && OpEqu(IsEnabled) &&
|
||||
OpEqu(SizeInMB) && OpEqu(IsFormatted) &&
|
||||
OpEqu(DateCreated) && OpEqu(DateModified);
|
||||
}
|
||||
|
||||
bool operator!=( const McdListItem& right ) const
|
||||
{
|
||||
return operator==( right );
|
||||
}
|
||||
bool operator==( const McdListItem& right ) const;
|
||||
bool operator!=( const McdListItem& right ) const;
|
||||
};
|
||||
|
||||
typedef std::vector<McdListItem> McdList;
|
||||
@ -75,12 +59,12 @@ typedef std::vector<McdListItem> McdList;
|
||||
class IMcdList
|
||||
{
|
||||
public:
|
||||
virtual void RefreshMcds() const=0;
|
||||
virtual int GetLength() const=0;
|
||||
virtual const McdListItem& GetCard( int idx ) const=0;
|
||||
virtual McdListItem& GetCard( int idx )=0;
|
||||
|
||||
virtual uint GetPort( int idx ) const=0;
|
||||
virtual uint GetSlot( int idx ) const=0;
|
||||
virtual wxDirName GetMcdPath() const=0;
|
||||
};
|
||||
|
||||
class BaseMcdListView : public wxListView
|
||||
@ -90,6 +74,9 @@ class BaseMcdListView : public wxListView
|
||||
protected:
|
||||
const IMcdList* m_CardProvider;
|
||||
|
||||
// specifies the target of a drag&drop operation
|
||||
int m_TargetedItem;
|
||||
|
||||
public:
|
||||
virtual ~BaseMcdListView() throw() { }
|
||||
BaseMcdListView( wxWindow* parent )
|
||||
@ -100,11 +87,26 @@ public:
|
||||
|
||||
virtual void SetCardCount( int length )=0;
|
||||
|
||||
virtual void SetInterface( IMcdList* face )
|
||||
virtual void SetMcdProvider( IMcdList* face )
|
||||
{
|
||||
m_CardProvider = face;
|
||||
SetCardCount( m_CardProvider ? m_CardProvider->GetLength() : 0 );
|
||||
}
|
||||
|
||||
virtual const IMcdList& GetMcdProvider() const
|
||||
{
|
||||
pxAssume( m_CardProvider );
|
||||
return *m_CardProvider;
|
||||
}
|
||||
|
||||
virtual void SetTargetedItem( int sel )
|
||||
{
|
||||
if( m_TargetedItem == sel ) return;
|
||||
|
||||
if( m_TargetedItem >= 0 ) RefreshItem( m_TargetedItem );
|
||||
m_TargetedItem = sel;
|
||||
RefreshItem( sel );
|
||||
}
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
@ -118,7 +120,6 @@ public:
|
||||
virtual ~MemoryCardListView_Simple() throw() { }
|
||||
MemoryCardListView_Simple( wxWindow* parent );
|
||||
|
||||
virtual void OnListDrag(wxListEvent& evt);
|
||||
void CreateColumns();
|
||||
virtual void SetCardCount( int length );
|
||||
|
||||
@ -142,7 +143,6 @@ public:
|
||||
virtual ~MemoryCardListView_Advanced() throw() { }
|
||||
MemoryCardListView_Advanced( wxWindow* parent );
|
||||
|
||||
virtual void OnListDrag(wxListEvent& evt);
|
||||
void CreateColumns();
|
||||
virtual void SetCardCount( int length );
|
||||
|
||||
@ -162,6 +162,7 @@ namespace Panels
|
||||
class BaseMcdListPanel
|
||||
: public BaseSelectorPanel
|
||||
, public wxFileDropTarget
|
||||
, public IMcdList // derived classes need to implement this
|
||||
{
|
||||
typedef BaseSelectorPanel _parent;
|
||||
|
||||
@ -173,6 +174,14 @@ namespace Panels
|
||||
wxBoxSizer* s_leftside_buttons;
|
||||
wxBoxSizer* s_rightside_buttons;
|
||||
|
||||
virtual void RefreshMcds() const;
|
||||
|
||||
virtual wxDirName GetMcdPath() const
|
||||
{
|
||||
pxAssume(m_FolderPicker);
|
||||
return m_FolderPicker->GetPath();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~BaseMcdListPanel() throw() {}
|
||||
BaseMcdListPanel( wxWindow* parent );
|
||||
@ -185,12 +194,11 @@ namespace Panels
|
||||
// --------------------------------------------------------------------------------------
|
||||
class MemoryCardListPanel_Simple
|
||||
: public BaseMcdListPanel
|
||||
, public IMcdList
|
||||
{
|
||||
typedef BaseMcdListPanel _parent;
|
||||
|
||||
protected:
|
||||
McdListItem m_Cards[2][4];
|
||||
McdListItem m_Cards[8];
|
||||
|
||||
// Doubles as Create and Delete buttons
|
||||
wxButton* m_button_Create;
|
||||
@ -208,10 +216,9 @@ namespace Panels
|
||||
|
||||
// Interface Implementation for IMcdList
|
||||
virtual int GetLength() const;
|
||||
|
||||
virtual const McdListItem& GetCard( int idx ) const;
|
||||
virtual McdListItem& GetCard( int idx );
|
||||
virtual uint GetPort( int idx ) const;
|
||||
virtual uint GetSlot( int idx ) const;
|
||||
|
||||
protected:
|
||||
void OnCreateCard(wxCommandEvent& evt);
|
||||
@ -232,7 +239,6 @@ namespace Panels
|
||||
// --------------------------------------------------------------------------------------
|
||||
class MemoryCardListPanel_Advanced
|
||||
: public BaseMcdListPanel
|
||||
, public IMcdList
|
||||
{
|
||||
typedef BaseMcdListPanel _parent;
|
||||
|
||||
@ -247,8 +253,6 @@ namespace Panels
|
||||
virtual int GetLength() const;
|
||||
virtual const McdListItem& GetCard( int idx ) const;
|
||||
virtual McdListItem& GetCard( int idx );
|
||||
virtual uint GetPort( int idx ) const;
|
||||
virtual uint GetSlot( int idx ) const;
|
||||
|
||||
protected:
|
||||
void OnCreateNewCard(wxCommandEvent& evt);
|
||||
@ -268,7 +272,7 @@ namespace Panels
|
||||
class MemoryCardInfoPanel : public BaseApplicableConfigPanel
|
||||
{
|
||||
protected:
|
||||
uint m_port;
|
||||
//uint m_port;
|
||||
uint m_slot;
|
||||
|
||||
wxString m_DisplayName;
|
||||
@ -277,7 +281,7 @@ namespace Panels
|
||||
|
||||
public:
|
||||
virtual ~MemoryCardInfoPanel() throw() {}
|
||||
MemoryCardInfoPanel( wxWindow* parent, uint port, uint slot );
|
||||
MemoryCardInfoPanel( wxWindow* parent, uint slot );
|
||||
void Apply();
|
||||
void Eject();
|
||||
|
||||
@ -332,7 +336,6 @@ namespace Panels
|
||||
|
||||
protected:
|
||||
int m_port;
|
||||
|
||||
pxCheckBox* m_check_Multitap;
|
||||
|
||||
public:
|
||||
|
@ -72,12 +72,6 @@ MemoryCardListView_Advanced::MemoryCardListView_Advanced( wxWindow* parent )
|
||||
: _parent( parent )
|
||||
{
|
||||
CreateColumns();
|
||||
Connect( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListView_Advanced::OnListDrag));
|
||||
}
|
||||
|
||||
void MemoryCardListView_Advanced::OnListDrag(wxListEvent& evt)
|
||||
{
|
||||
evt.Skip();
|
||||
}
|
||||
|
||||
// return the text for the given column of the given item
|
||||
@ -91,8 +85,8 @@ wxString MemoryCardListView_Advanced::OnGetItemText(long item, long column) cons
|
||||
{
|
||||
case McdCol_Mounted:
|
||||
{
|
||||
if( (it.Port == -1) && (it.Slot == -1) ) return L"No";
|
||||
return wxsFormat( L"%u / %u", it.Port+1, it.Slot+1);
|
||||
if( !it.IsEnabled ) return _("No");
|
||||
return wxsFormat( L"%u", it.Slot+1);
|
||||
}
|
||||
|
||||
case McdCol_Filename: return it.Filename.GetName();
|
||||
@ -133,10 +127,9 @@ wxListItemAttr* MemoryCardListView_Advanced::OnGetItemAttr(long item) const
|
||||
// =====================================================================================================
|
||||
// MemoryCardInfoPanel
|
||||
// =====================================================================================================
|
||||
MemoryCardInfoPanel::MemoryCardInfoPanel( wxWindow* parent, uint port, uint slot )
|
||||
MemoryCardInfoPanel::MemoryCardInfoPanel( wxWindow* parent, uint slot )
|
||||
: BaseApplicableConfigPanel( parent, wxVERTICAL ) //, wxEmptyString )
|
||||
{
|
||||
m_port = port;
|
||||
m_slot = slot;
|
||||
|
||||
SetMinSize( wxSize(128, 48) );
|
||||
@ -198,11 +191,11 @@ void MemoryCardInfoPanel::Apply()
|
||||
Eject();
|
||||
throw Exception::CannotApplySettings( this,
|
||||
// Diagnostic
|
||||
wxsFormat( L"Memorycard in Port %u, Slot %u conflicts with an existing directory.", m_port, m_slot ),
|
||||
wxsFormat( L"Memorycard in slot %u conflicts with an existing directory.", m_slot ),
|
||||
// Translated
|
||||
wxsFormat(
|
||||
_("Cannot use or create the memorycard in Port %u, Slot %u: the filename conflicts with an existing directory."),
|
||||
m_port, m_slot
|
||||
_("Cannot use or create the memorycard in slot %u: the filename conflicts with an existing directory."),
|
||||
m_slot
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -212,24 +205,24 @@ void MemoryCardInfoPanel::Apply()
|
||||
Eject();
|
||||
throw Exception::CannotApplySettings( this,
|
||||
// Diagnostic
|
||||
wxsFormat( L"Memorycard in Port %u, Slot %u is no longer valid.", m_port, m_slot ),
|
||||
wxsFormat( L"Memorycard in slot %u is no longer valid.", m_slot ),
|
||||
// Translated
|
||||
wxsFormat(
|
||||
_("The configured memorycard in Port %u, Slot %u no longer exists. Please create a new memory card, or leave the slot unmounted."),
|
||||
m_port, m_slot
|
||||
_("The configured memorycard in slot %u no longer exists. Please create a new memory card, or leave the slot unmounted."),
|
||||
m_slot
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
g_Conf->Mcd[m_port][m_slot].Filename = m_cardInfo->Filename;
|
||||
g_Conf->Mcd[m_port][m_slot].Enabled = true;
|
||||
g_Conf->Mcd[m_slot].Filename = m_cardInfo->Filename;
|
||||
g_Conf->Mcd[m_slot].Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Card is either disabled or in an error state.
|
||||
|
||||
g_Conf->Mcd[m_port][m_slot].Enabled = false;
|
||||
g_Conf->Mcd[m_port][m_slot].Filename.Clear();
|
||||
g_Conf->Mcd[m_slot].Enabled = false;
|
||||
g_Conf->Mcd[m_slot].Filename.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,7 +232,7 @@ void MemoryCardInfoPanel::AppStatusEvent_OnSettingsApplied()
|
||||
|
||||
// Collect Info and Format Strings
|
||||
|
||||
wxString fname( g_Conf->Mcd[m_port][m_slot].Filename.GetFullPath() );
|
||||
wxString fname( g_Conf->Mcd[m_slot].Filename.GetFullPath() );
|
||||
if( fname.IsEmpty() )
|
||||
{
|
||||
m_DisplayName = _("No Card (empty)");
|
||||
@ -277,12 +270,9 @@ Panels::MemoryCardsPanel::MemoryCardsPanel( wxWindow* parent )
|
||||
{
|
||||
m_panel_AllKnownCards = new MemoryCardListPanel_Advanced( this );
|
||||
|
||||
for( uint port=0; port<2; ++port )
|
||||
for( uint slot=0; slot<2; ++slot )
|
||||
{
|
||||
for( uint slot=0; slot<1; ++slot )
|
||||
{
|
||||
m_panel_cardinfo[port][slot] = new MemoryCardInfoPanel( this, port, slot );
|
||||
}
|
||||
m_panel_cardinfo[slot] = new MemoryCardInfoPanel( this, slot );
|
||||
}
|
||||
|
||||
// ------------------------------------
|
||||
|
@ -2769,6 +2769,10 @@
|
||||
RelativePath="..\..\gui\MainFrame.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\MemoryCardFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\pxEventThread.h"
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user