diff options
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/DolphinWX/Src/MemcardManager.cpp | 295 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/Src/MemcardManager.h | 29 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp | 207 | ||||
| -rw-r--r-- | Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h | 26 |
4 files changed, 446 insertions, 111 deletions
diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp index 971dc64875..2bba44fb20 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.cpp +++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp @@ -74,7 +74,8 @@ BEGIN_EVENT_TABLE(CMemcardManager, wxDialog) EVT_CLOSE(CMemcardManager::OnClose)
EVT_BUTTON(ID_COPYTOLEFT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_COPYTORIGHT,CMemcardManager::CopyDeleteClick)
- EVT_BUTTON(ID_FIXCHECKSUM,CMemcardManager::CopyDeleteClick)
+ EVT_BUTTON(ID_FIXCHECKSUMLEFT,CMemcardManager::CopyDeleteClick)
+ EVT_BUTTON(ID_FIXCHECKSUMRIGHT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_DELETELEFT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_DELETERIGHT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_SAVEIMPORTRIGHT,CMemcardManager::CopyDeleteClick)
@@ -82,6 +83,10 @@ BEGIN_EVENT_TABLE(CMemcardManager, wxDialog) EVT_BUTTON(ID_SAVEIMPORTLEFT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_SAVEEXPORTLEFT,CMemcardManager::CopyDeleteClick)
EVT_BUTTON(ID_CONVERTTOGCI,CMemcardManager::CopyDeleteClick)
+ EVT_BUTTON(ID_MEMCARD1PREVPAGE, CMemcardManager::OnPageChange)
+ EVT_BUTTON(ID_MEMCARD1NEXTPAGE, CMemcardManager::OnPageChange)
+ EVT_BUTTON(ID_MEMCARD2PREVPAGE, CMemcardManager::OnPageChange)
+ EVT_BUTTON(ID_MEMCARD2NEXTPAGE, CMemcardManager::OnPageChange)
EVT_FILEPICKER_CHANGED(ID_MEMCARD1PATH,CMemcardManager::OnPathChange)
EVT_FILEPICKER_CHANGED(ID_MEMCARD2PATH,CMemcardManager::OnPathChange)
END_EVENT_TABLE()
@@ -110,29 +115,39 @@ CMemcardManager::~CMemcardManager() void CMemcardManager::CreateGUIControls()
{
+ t_StatusLeft = new wxStaticText(this, 0, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString);
+ t_StatusRight = new wxStaticText(this, 0, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxEmptyString);
+
// buttons
m_CopyToLeft = new wxButton(this, ID_COPYTOLEFT, wxT("<-Copy<-"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_CopyToRight = new wxButton(this, ID_COPYTORIGHT, wxT("->Copy->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
- m_FixChecksum = new wxButton(this, ID_FIXCHECKSUM, wxT("<-Fix\nChecksum"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+ m_FixChecksumLeft = new wxButton(this, ID_FIXCHECKSUMLEFT, wxT("<-Fix Checksum"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+ m_FixChecksumRight = new wxButton(this, ID_FIXCHECKSUMRIGHT, wxT("Fix Checksum->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_SaveImportLeft = new wxButton(this, ID_SAVEIMPORTLEFT, wxT("<-Import GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
- m_SaveExportLeft = new wxButton(this, ID_SAVEEXPORTLEFT, wxT("<-Export GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_SaveImportRight = new wxButton(this, ID_SAVEIMPORTRIGHT, wxT("Import GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+
+ m_SaveExportLeft = new wxButton(this, ID_SAVEEXPORTLEFT, wxT("<-Export GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_SaveExportRight = new wxButton(this, ID_SAVEEXPORTRIGHT, wxT("Export GCI->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
- //Added to test GCS and SAV import, until ImportFile is fixed
- //rather than needing to import and then export
+
m_ConvertToGci = new wxButton(this, ID_CONVERTTOGCI, wxT("Convert to GCI"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_DeleteLeft = new wxButton(this, ID_DELETELEFT, wxT("<-Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_DeleteRight = new wxButton(this, ID_DELETERIGHT, wxT("Delete->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+ m_Memcard1PrevPage = new wxButton(this, ID_MEMCARD1PREVPAGE, wxT("Prev Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+ m_Memcard2PrevPage = new wxButton(this, ID_MEMCARD2PREVPAGE, wxT("Prev Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+
+ m_Memcard1NextPage = new wxButton(this, ID_MEMCARD1NEXTPAGE, wxT("Next Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+ m_Memcard2NextPage = new wxButton(this, ID_MEMCARD2NEXTPAGE, wxT("Next Page"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
+
// Sizers that double as wxStaticBoxes
sMemcard1 = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card 1"));
sMemcard2 = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card 2"));
// Create the controls for both memcards
- // Loading invalid .raw files still crash the app, but eh, needed this for testing
+ // Loading invalid .raw files should no longer crash the app
m_Memcard1Path = new wxFilePickerCtrl(this, ID_MEMCARD1PATH, wxEmptyString, wxT("Choose a memory card:"),
wxT("Raw memcards (*.raw)|*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN);
m_Memcard2Path = new wxFilePickerCtrl(this, ID_MEMCARD2PATH, wxEmptyString, wxT("Choose a memory card:"),
@@ -153,7 +168,8 @@ void CMemcardManager::CreateGUIControls() sButtons->Add(m_CopyToLeft, 0, wxEXPAND, 5);
sButtons->Add(m_CopyToRight, 0, wxEXPAND, 5);
sButtons->AddStretchSpacer(1);
- sButtons->Add(m_FixChecksum, 0, wxEXPAND, 5);
+ sButtons->Add(m_FixChecksumLeft, 0, wxEXPAND, 5);
+ sButtons->Add(m_FixChecksumRight, 0, wxEXPAND, 5);
sButtons->AddStretchSpacer(1);
sButtons->Add(m_SaveImportLeft, 0, wxEXPAND, 5);
sButtons->Add(m_SaveExportLeft, 0, wxEXPAND, 5);
@@ -167,19 +183,47 @@ void CMemcardManager::CreateGUIControls() sButtons->Add(m_DeleteRight, 0, wxEXPAND, 5);
sButtons->AddStretchSpacer(1);
+ sPagesLeft = new wxBoxSizer(wxHORIZONTAL);
+ sPagesRight = new wxBoxSizer(wxHORIZONTAL);
+
+ sPagesLeft->Add(m_Memcard1PrevPage, 0, wxEXPAND|wxALL, 1);
+ sPagesLeft->Add(t_StatusLeft,0, wxEXPAND|wxALL, 5);
+ sPagesLeft->Add(0, 0, 1, wxEXPAND|wxALL, 0);
+ sPagesLeft->Add(m_Memcard1NextPage, 0, wxEXPAND|wxALL, 1);
+ sPagesRight->Add(m_Memcard2PrevPage, 0, wxEXPAND|wxALL, 1);
+ sPagesRight->Add(t_StatusRight, 0, wxEXPAND|wxALL, 5);
+ sPagesRight->Add(0, 0, 1, wxEXPAND|wxALL, 0);
+ sPagesRight->Add(m_Memcard2NextPage, 0, wxEXPAND|wxALL, 1);
+
sMemcard1->Add(m_Memcard1Path, 0, wxEXPAND|wxALL, 5);
- sMemcard1->Add(m_MemcardList[0], 1, wxEXPAND|wxALL, 5);
+ sMemcard1->Add(m_MemcardList[0], 1, wxEXPAND|wxALL, 5);
+ sMemcard1->Add(sPagesLeft, 0, wxEXPAND|wxALL, 1);
sMemcard2->Add(m_Memcard2Path, 0, wxEXPAND|wxALL, 5);
sMemcard2->Add(m_MemcardList[1], 1, wxEXPAND|wxALL, 5);
+ sMemcard2->Add(sPagesRight, 0, wxEXPAND|wxALL, 1);
sMain = new wxBoxSizer(wxHORIZONTAL);
sMain->Add(sMemcard1, 1, wxEXPAND|wxALL, 5);
sMain->Add(sButtons, 0, wxEXPAND, 0);
sMain->Add(sMemcard2, 1, wxEXPAND|wxALL, 5);
-
+
this->SetSizer(sMain);
sMain->SetSizeHints(this);
Fit();
+ m_Memcard1PrevPage->Disable();
+ m_Memcard1NextPage->Disable();
+ m_Memcard2PrevPage->Disable();
+ m_Memcard2NextPage->Disable();
+ m_CopyToLeft->Disable();
+ m_CopyToRight->Disable();
+ m_FixChecksumLeft->Disable();
+ m_FixChecksumRight->Disable();
+ m_SaveImportLeft->Disable();
+ m_SaveExportLeft->Disable();
+ m_SaveImportRight->Disable();
+ m_SaveExportRight->Disable();
+ m_DeleteLeft->Disable();
+ m_DeleteRight->Disable();
}
void CMemcardManager::OnClose(wxCloseEvent& WXUNUSED (event))
@@ -192,10 +236,100 @@ void CMemcardManager::OnPathChange(wxFileDirPickerEvent& event) switch (event.GetId())
{
case ID_MEMCARD1PATH:
- ReloadMemcard(event.GetPath().mb_str(), 0);
+ page1 = 0;
+ if (m_Memcard1PrevPage->IsEnabled()) m_Memcard1PrevPage->Disable();
+ if (!strcasecmp(m_Memcard1Path->GetPath().mb_str(),m_Memcard2Path->GetPath().mb_str()))
+ {
+ wxMessageBox(wxT("Memcard already opened"), wxT("Error"), wxOK|wxICON_ERROR);
+ m_Memcard1Path->SetPath(wxEmptyString);
+ m_MemcardList[0]->ClearAll();
+ t_StatusLeft->SetLabel(wxEmptyString);
+ }
+ else if (ReloadMemcard(event.GetPath().mb_str(), 0, page1))
+ {
+ m_FixChecksumLeft->Enable();
+ m_SaveImportLeft->Enable();
+ m_SaveExportLeft->Enable();
+ m_DeleteLeft->Enable();
+ break;
+ }
+ m_Memcard1Path->SetPath(wxEmptyString);
+ m_MemcardList[0]->ClearAll();
+ t_StatusLeft->SetLabel(wxEmptyString);
+ m_FixChecksumLeft->Disable();
+ m_SaveImportLeft->Disable();
+ m_SaveExportLeft->Disable();
+ m_DeleteLeft->Disable();
+ m_Memcard1PrevPage->Disable();
+ m_Memcard1NextPage->Disable();
break;
case ID_MEMCARD2PATH:
- ReloadMemcard(event.GetPath().mb_str(), 1);
+ page2 = 0;
+ if (m_Memcard2PrevPage->IsEnabled()) m_Memcard2PrevPage->Disable();
+ if (!strcasecmp(m_Memcard1Path->GetPath().mb_str(),m_Memcard2Path->GetPath().mb_str()))
+ {
+ wxMessageBox(wxT("Memcard already opened"), wxT("Error"), wxOK|wxICON_ERROR);
+ }
+ else if (ReloadMemcard(event.GetPath().mb_str(), 1, page2))
+ {
+ m_FixChecksumRight->Enable();
+ m_SaveImportRight->Enable();
+ m_SaveExportRight->Enable();
+ m_DeleteRight->Enable();
+ break;
+ }
+ m_Memcard2Path->SetPath(wxEmptyString);
+ m_MemcardList[1]->ClearAll();
+ t_StatusRight->SetLabel(wxEmptyString);
+ m_FixChecksumRight->Disable();
+ m_SaveImportRight->Disable();
+ m_SaveExportRight->Disable();
+ m_DeleteRight->Disable();
+ m_Memcard2PrevPage->Disable();
+ m_Memcard2NextPage->Disable();
+ break;
+ }
+ if (m_DeleteRight->IsEnabled() && m_DeleteLeft->IsEnabled())
+ {
+ m_CopyToLeft->Enable();
+ m_CopyToRight->Enable();
+ }
+ else
+ {
+ m_CopyToLeft->Disable();
+ m_CopyToRight->Disable();
+ }
+}
+
+void CMemcardManager::OnPageChange(wxCommandEvent& event)
+{
+ switch (event.GetId())
+ {
+ case ID_MEMCARD1NEXTPAGE:
+ if (!m_Memcard1PrevPage->IsEnabled()) m_Memcard1PrevPage->Enable();
+ if (!m_Memcard1NextPage->IsEnabled()) m_Memcard1NextPage->Enable();
+ page1++;
+ if (page1 == 7) m_Memcard1NextPage->Disable();
+ ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0, page1);
+ break;
+ case ID_MEMCARD2NEXTPAGE:
+ if (!m_Memcard2PrevPage->IsEnabled()) m_Memcard2PrevPage->Enable();
+ if (!m_Memcard2NextPage->IsEnabled()) m_Memcard2NextPage->Enable();
+ page2++;
+ if (page2 == 7) m_Memcard2NextPage->Disable();
+ ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1, page2);
+ break;
+ case ID_MEMCARD1PREVPAGE:
+ if (!m_Memcard1NextPage->IsEnabled()) m_Memcard1NextPage->Enable();
+ page1--;
+ if (page1 == 0) m_Memcard1PrevPage->Disable();
+ ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0, page1);
+ break;
+ case ID_MEMCARD2PREVPAGE:
+ if (!m_Memcard2NextPage->IsEnabled()) m_Memcard2NextPage->Enable();
+ page2--;
+ if (page2 == 0) m_Memcard2PrevPage->Disable();
+ ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1, page2);
break;
}
}
@@ -207,7 +341,6 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) int slot = 1;
int index2 = index1;
std::string fileName2("");
- int freeBlocks = 0;
wxString blocksOpen;
switch (event.GetId())
@@ -225,11 +358,15 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) break;
case SUCCESS:
memoryCard[0]->Save();
- ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
+ ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0, 0);
break;
}
}
+ else
+ {
+ wxMessageBox(wxT("You have not selected a save to copy"), wxT("Error"), wxOK|wxICON_ERROR);
+ }
break;
case ID_COPYTORIGHT:
if ((index0 != -1) && (memoryCard[1] != NULL))
@@ -246,19 +383,29 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) break;
case SUCCESS:
memoryCard[1]->Save();
- ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1);
+ ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1, 0);
break;
}
}
+ else
+ {
+ wxMessageBox(wxT("You have not selected a save to copy"), wxT("Error"), wxOK|wxICON_ERROR);
+ }
break;
- case ID_FIXCHECKSUM:
- if (memoryCard[0] != NULL)
+ case ID_FIXCHECKSUMLEFT:
+ slot = 0;
+ case ID_FIXCHECKSUMRIGHT:
+ if (memoryCard[slot] != NULL)
{
// Fix checksums and save the changes
- memoryCard[0]->FixChecksums() ? wxMessageBox(wxT("The checksum was successfully fixed"), wxT("Success"), wxOK)
+ memoryCard[slot]->FixChecksums() ? wxMessageBox(wxT("The checksum was successfully fixed"), wxT("Success"), wxOK)
: wxMessageBox(wxT("The checksum could not be successfully fixed"), wxT("Error"), wxOK|wxICON_ERROR);
- memoryCard[0]->Save();
- }
+ memoryCard[slot]->Save();
+ }
+ else
+ {
+ wxMessageBox(wxT("memorycard is not loaded"), wxT("Error"), wxOK|wxICON_ERROR);
+ }
break;
case ID_CONVERTTOGCI:
fileName2 = "convert";
@@ -268,7 +415,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) case ID_SAVEIMPORTRIGHT:
if (memoryCard[slot] != NULL || !fileName2.empty())
{
- wxString temp = wxFileSelector(_T("Select the GCI file to import"),
+ wxString temp = wxFileSelector(_T("Select a save file to import"),
wxEmptyString, wxEmptyString, wxEmptyString,wxString::Format
(
_T("Gamecube save files(*.gci,*.gcs,*.sav)|*.gci;*.gcs;*.sav|"
@@ -290,6 +437,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) wxFileSelectorDefaultWildcardStr
),
wxFD_OVERWRITE_PROMPT|wxFD_SAVE);
+ if (temp2.empty()) break;
fileName2 = temp2.mb_str();
}
if (temp.length() > 0)
@@ -320,8 +468,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) wxT("Success"), wxOK);
break;
case OUTOFBLOCKS:
- freeBlocks = BE16(memoryCard[slot]->bat.FreeBlocks);
- blocksOpen.Printf(wxT("Only %d blocks available"), freeBlocks);
+ blocksOpen.Printf(wxT("Only %d blocks available"), memoryCard[slot]->GetFreeBlocks());
wxMessageBox(blocksOpen, wxT("Error"), wxOK|wxICON_ERROR);
break;
case OUTOFDIRENTRIES:
@@ -342,12 +489,16 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) break;
default:
memoryCard[slot]->Save();
- slot == 1 ? ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1)
- : ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
+ slot == 1 ? ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1, 0)
+ : ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0, 0);
break;
}
}
}
+ else
+ {
+ wxMessageBox(wxT("Memory card is not loaded"), wxT("Error"), wxOK|wxICON_ERROR);
+ }
break;
case ID_SAVEEXPORTLEFT:
slot=0;
@@ -387,6 +538,10 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) }
}
}
+ else
+ {
+ wxMessageBox(wxT("You have not selected a save to export"), wxT("Error"), wxOK|wxICON_ERROR);
+ }
break;
case ID_DELETELEFT:
slot=0;
@@ -406,28 +561,41 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) break;
case SUCCESS:
memoryCard[slot]->Save();
- slot == 1 ? ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1)
- : ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
+ slot == 1 ? ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1, 0)
+ : ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0, 0);
break;
}
}
+ else
+ {
+ wxMessageBox(wxT("You have not selected a save to delete"), wxT("Error"), wxOK|wxICON_ERROR);
+ }
break;
}
}
-void CMemcardManager::ReloadMemcard(const char *fileName, int card)
+bool CMemcardManager::ReloadMemcard(const char *fileName, int card, int page)
{
+ wxString wxBlock;
+ wxString wxFirstBlock;
+ wxString wxLabel;
+ int j;
+
if (memoryCard[card]) delete memoryCard[card];
// TODO: add error checking and animate icons
memoryCard[card] = new GCMemcard(fileName);
+ if (ReadError(memoryCard[card])) return false;
+
m_MemcardList[card]->Hide();
m_MemcardList[card]->ClearAll();
m_MemcardList[card]->InsertColumn(COLUMN_BANNER, _T("Banner"));
m_MemcardList[card]->InsertColumn(COLUMN_TITLE, _T("Title"));
m_MemcardList[card]->InsertColumn(COLUMN_COMMENT, _T("Comment"));
m_MemcardList[card]->InsertColumn(COLUMN_ICON, _T("Icon"));
+ m_MemcardList[card]->InsertColumn(COLUMN_BLOCKS, _T("Blocks"));
+ m_MemcardList[card]->InsertColumn(COLUMN_FIRSTBLOCK, _T("First Block"));
wxImageList *list = m_MemcardList[card]->GetImageList(wxIMAGE_LIST_SMALL);
list->RemoveAll();
@@ -435,7 +603,7 @@ void CMemcardManager::ReloadMemcard(const char *fileName, int card) int nFiles = memoryCard[card]->GetNumFiles();
int *images = new int[nFiles*2];
- for (int i=0;i<nFiles;i++)
+ for (int i = 0;i < nFiles;i++)
{
static u32 pxdata[96*32];
static u8 animDelay[8];
@@ -483,27 +651,43 @@ void CMemcardManager::ReloadMemcard(const char *fileName, int card) images[i*2+1] = list->Add(icon);
}
}
-
- for (int i=0;i<nFiles;i++)
+ for (j = page * 16;(j < nFiles) && (j < (page + 1)* 16);j++)
{
char title[32];
char comment[32];
+ u16 blocks;
+ u16 firstblock;
- if (!memoryCard[card]->GetComment1(i,title)) title[0]=0;
- if (!memoryCard[card]->GetComment2(i,comment)) comment[0]=0;
- int index = m_MemcardList[card]->InsertItem(i, wxT("row"));
+ if (!memoryCard[card]->GetComment1(j, title)) title[0]=0;
+ if (!memoryCard[card]->GetComment2(j, comment)) comment[0]=0;
+ int index = m_MemcardList[card]->InsertItem(j, wxT("row"));
m_MemcardList[card]->SetItem(index, COLUMN_BANNER, wxEmptyString);
m_MemcardList[card]->SetItem(index, COLUMN_TITLE, wxString::FromAscii(title));
m_MemcardList[card]->SetItem(index, COLUMN_COMMENT, wxString::FromAscii(comment));
+ if (!memoryCard[card]->GetNumBlocks(j, &blocks)) blocks = 0;
+ wxBlock.Printf("%10d", blocks);
+ if (!memoryCard[card]->GetFirstBlock(j,&firstblock)) firstblock = 0;
+ wxFirstBlock.Printf("%10d", firstblock-4);
+ m_MemcardList[card]->SetItem(index,COLUMN_BLOCKS, wxBlock);
+ m_MemcardList[card]->SetItem(index,COLUMN_FIRSTBLOCK, wxFirstBlock);
m_MemcardList[card]->SetItem(index, COLUMN_ICON, wxEmptyString);
- if (images[i]>=0)
+ if (images[j] >= 0)
{
- m_MemcardList[card]->SetItemImage(index, images[i*2]);
- m_MemcardList[card]->SetItemColumnImage(index, COLUMN_ICON, images[i*2+1]);
+ m_MemcardList[card]->SetItemImage(index, images[j*2]);
+ m_MemcardList[card]->SetItemColumnImage(index, COLUMN_ICON, images[j*2+1]);
}
}
+ if (j == nFiles)
+ {
+ card ? m_Memcard2NextPage->Disable() : m_Memcard1NextPage->Disable();
+ }
+ else
+ {
+ card ? m_Memcard2NextPage->Enable() : m_Memcard1NextPage->Enable();
+ }
+
delete[] images;
// Automatic column width and then show the list
for (int i = 0; i < m_MemcardList[card]->GetColumnCount(); i++)
@@ -511,4 +695,43 @@ void CMemcardManager::ReloadMemcard(const char *fileName, int card) m_MemcardList[card]->SetColumnWidth(i, wxLIST_AUTOSIZE);
}
m_MemcardList[card]->Show();
+ wxLabel.Printf("%d Free Blocks; %d Free Dir Entries",
+ memoryCard[card]->GetFreeBlocks(), 127 - nFiles);
+ card ? t_StatusRight->SetLabel(wxLabel) : t_StatusLeft->SetLabel(wxLabel);
+
+ return true;
+}
+
+bool CMemcardManager::ReadError(GCMemcard *memcard)
+{
+ if (!memcard->fail[0]) return false;
+ wxString wxBlock;
+ if (memcard->fail[HDR_READ_ERROR]) wxMessageBox(wxT("Failed to read header correctly\n(0x0000-0x1FFF)"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[DIR_READ_ERROR]) wxMessageBox(wxT("Failed to read directory correctly\n(0x2000-0x3FFF)"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[DIR_BAK_READ_ERROR]) wxMessageBox(wxT("Failed to read directory backup correctly\n(0x4000-0x5FFF)"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[BAT_READ_ERROR]) wxMessageBox(wxT("Failed to read block allocation table correctly\n(0x6000-0x7FFF)"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[BAT_BAK_READ_ERROR]) wxMessageBox(wxT("Failed to read block allocation table backup correctly\n(0x8000-0x9FFF)"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[HDR_CSUM_FAIL]) wxMessageBox(wxT("Header checksum failed"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[DIR_CSUM_FAIL])
+ {
+ wxMessageBox(wxT("Directory checksum failed"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ wxMessageBox(wxT("Directory backup checksum failed"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ }
+ if (memcard->fail[BAT_CSUM_FAIL]) wxMessageBox(wxT("Block Allocation Table checksum failed"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[DATA_READ_FAIL]) wxMessageBox(wxT("Failed to read save data\n(0xA000-)\nMemcard may be truncated"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[HDR_SIZE_FFFF]) wxMessageBox(wxT("Memcard failed to load\n Card size is invalid"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ if (memcard->fail[NOTRAWORGCP]) wxMessageBox(wxT("File does not have a valid extension (.raw/.gcp)"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ return true;
}
diff --git a/Source/Core/DolphinWX/Src/MemcardManager.h b/Source/Core/DolphinWX/Src/MemcardManager.h index 962b4f78cb..7e8f8813a8 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.h +++ b/Source/Core/DolphinWX/Src/MemcardManager.h @@ -26,7 +26,6 @@ #include <wx/imaglist.h>
#include "MemoryCards/GCMemcard.h"
-#define BE16(x) ((u16((x)[0])<<8) | u16((x)[1]))
#undef MEMCARD_MANAGER_STYLE
#define MEMCARD_MANAGER_STYLE wxCAPTION | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxCLOSE_BOX | wxRESIZE_BORDER | wxMAXIMIZE_BOX
@@ -42,10 +41,18 @@ class CMemcardManager DECLARE_EVENT_TABLE();
+ int page1,
+ page2;
+
wxBoxSizer *sMain;
+ wxBoxSizer *sPagesLeft;
+ wxBoxSizer *sPagesRight;
+ wxStaticText *t_StatusLeft;
+ wxStaticText *t_StatusRight;
wxButton *m_CopyToLeft;
wxButton *m_CopyToRight;
- wxButton *m_FixChecksum;
+ wxButton *m_FixChecksumLeft;
+ wxButton *m_FixChecksumRight;
wxButton *m_SaveImportLeft;
wxButton *m_SaveExportLeft;
wxButton *m_SaveImportRight;
@@ -53,6 +60,10 @@ class CMemcardManager wxButton *m_ConvertToGci;
wxButton *m_DeleteLeft;
wxButton *m_DeleteRight;
+ wxButton *m_Memcard1PrevPage;
+ wxButton *m_Memcard1NextPage;
+ wxButton *m_Memcard2PrevPage;
+ wxButton *m_Memcard2NextPage;
wxStaticBoxSizer *sMemcard1;
wxStaticBoxSizer *sMemcard2;
wxFilePickerCtrl *m_Memcard1Path;
@@ -64,11 +75,16 @@ class CMemcardManager {
ID_COPYTORIGHT = 1000,
ID_COPYTOLEFT,
- ID_FIXCHECKSUM,
+ ID_FIXCHECKSUMRIGHT,
+ ID_FIXCHECKSUMLEFT,
ID_DELETERIGHT,
ID_DELETELEFT,
ID_MEMCARD1PATH,
ID_MEMCARD2PATH,
+ ID_MEMCARD1NEXTPAGE,
+ ID_MEMCARD1PREVPAGE,
+ ID_MEMCARD2NEXTPAGE,
+ ID_MEMCARD2PREVPAGE,
ID_SAVEEXPORTRIGHT,
ID_SAVEEXPORTLEFT,
ID_SAVEIMPORTRIGHT,
@@ -85,6 +101,8 @@ class CMemcardManager COLUMN_TITLE,
COLUMN_COMMENT,
COLUMN_ICON,
+ COLUMN_BLOCKS,
+ COLUMN_FIRSTBLOCK,
NUMBER_OF_COLUMN
};
@@ -93,9 +111,10 @@ class CMemcardManager void CreateGUIControls();
void OnClose(wxCloseEvent& event);
void CopyDeleteClick(wxCommandEvent& event);
- void ReloadMemcard(const char *fileName, int card);
+ bool ReloadMemcard(const char *fileName, int card, int page);
+ void OnPageChange(wxCommandEvent& event);
void OnPathChange(wxFileDirPickerEvent& event);
- void OnTimer(wxTimerEvent& event);
+ bool ReadError(GCMemcard *memcard);
};
#endif
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp index 1efbbd3dfd..f284ee1e37 100644 --- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp @@ -25,7 +25,6 @@ // i think there is support for this stuff in the common lib... if not there should be support
-// and to get a file exentions there is a function called SplitPath()
#define BE16(x) ((u16((x)[0])<<8) | u16((x)[1]))
#define BE32(x) ((u32((x)[0])<<24) | (u32((x)[1])<<16) | (u32((x)[2])<<8) | u32((x)[3]))
#define ArrayByteSwap(a) (ByteSwap(a, a+sizeof(u8)));
@@ -54,24 +53,30 @@ u32 __inline bswap32(u32 s) void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
{
- *c1 = 0;*c2 = 0;
- for (u32 i = 0; i < num; ++i)
- {
- //weird warnings here
- *c1 += bswap16(buf[i]);
- *c2 += bswap16((u16)(buf[i] ^ 0xffff));
- }
- if (*c1 == 0xffff)
- {
- *c1 = 0;
- }
- if (*c2 == 0xffff)
- {
- *c2 = 0;
- }
+ *c1 = 0;*c2 = 0;
+ for (u32 i = 0; i < num; ++i)
+ {
+ //weird warnings here
+ *c1 += bswap16(buf[i]);
+ *c2 += bswap16((u16)(buf[i] ^ 0xffff));
+ }
+ if (*c1 == 0xffff)
+ {
+ *c1 = 0;
+ }
+ if (*c2 == 0xffff)
+ {
+ *c2 = 0;
+ }
+}
+
+u16 GCMemcard::GetFreeBlocks(void)
+{
+ if (!mcdFile) return 0;
+ return BE16(bat.FreeBlocks);
}
-u32 GCMemcard::GetNumFiles()
+u32 GCMemcard::GetNumFiles()
{
if (!mcdFile) return 0;
int j = 0;
@@ -83,7 +88,7 @@ u32 GCMemcard::GetNumFiles() return j;
}
-bool GCMemcard::titlePresent(DEntry d)
+bool GCMemcard::TitlePresent(DEntry d)
{
//TODO: Clean up this function
bool equal = false;
@@ -114,6 +119,20 @@ bool GCMemcard::titlePresent(DEntry d) return false;
}
+bool GCMemcard::GetNumBlocks(u32 index, u16* buffer)
+{
+ if (!mcdFile) return false;
+ *buffer = BE16(dir.Dir[index].BlockCount);
+ return true;
+}
+
+bool GCMemcard::GetFirstBlock(u32 index, u16* buffer)
+{
+ if (!mcdFile) return false;
+ *buffer = BE16(dir.Dir[index].FirstBlock);
+ return true;
+}
+
u32 GCMemcard::RemoveFile(u32 index) //index in the directory array
{
if (!mcdFile) return NOMEMCARD;
@@ -130,7 +149,7 @@ u32 GCMemcard::RemoveFile(u32 index) //index in the directory array int i = index + 1;
memset(&(dir.Dir[index]), 0xFF, 0x40);
-
+
while (i < 127)
{
DEntry * d = new DEntry;
@@ -196,7 +215,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove) {
return OUTOFBLOCKS;
}
- if (!remove && titlePresent(direntry)) return TITLEPRESENT;
+ if (!remove && TitlePresent(direntry)) return TITLEPRESENT;
// find first free data block -- assume no freespace fragmentation
int totalspace = (((u32)BE16(hdr.Size) * 16) - 5);
@@ -293,9 +312,9 @@ u32 GCMemcard::GetFileData(u32 index, u8*dest, bool old) //index in the director {
if (!mcdFile) return NOMEMCARD;
- int block = BE16(dir.Dir[index].FirstBlock);
- int saveLength = BE16(dir.Dir[index].BlockCount);
- int memcardSize = BE16(hdr.Size) * 0x0010;
+ u16 block = BE16(dir.Dir[index].FirstBlock);
+ u16 saveLength = BE16(dir.Dir[index].BlockCount);
+ u16 memcardSize = BE16(hdr.Size) * 0x0010;
if (block + saveLength > memcardSize)
{
@@ -308,27 +327,24 @@ u32 GCMemcard::GetFileData(u32 index, u8*dest, bool old) //index in the director }
else
{
- assert(block != 0xFFFF);
assert(block > 0);
- do
- {
- memcpy(dest,mc_data + 0x2000 * (block - 5), 0x2000);
- dest+=0x2000;
-
+ while (block != 0xffff)
+ {
+ memcpy(dest,mc_data + 0x2000 * (block - 5), 0x2000);
+ dest+=0x2000;
- int nextblock = bswap16(bat.Map[block - 5]);
- if (block + saveLength != memcardSize && nextblock > 0)
- {//Fixes for older memcards that were not initialized with FF
- block = nextblock;
- }
- else block = 0xffff;
- }
- while (block != 0xffff);
+ u16 nextblock = bswap16(bat.Map[block - 5]);
+ if (block + saveLength != memcardSize && nextblock > 0)
+ {//Fixes for older memcards that were not initialized with FF
+ block = nextblock;
+ }
+ else break;
+ }
}
return SUCCESS;
}
-u32 GCMemcard::GetFileSize(u32 index) //index in the directory array
+u32 GCMemcard::GetFileSize(u32 index) //index in the directory array
{
if (!mcdFile) return 0;
@@ -342,6 +358,7 @@ bool GCMemcard::GetFileInfo(u32 index, GCMemcard::DEntry& info) //index in the d info = dir.Dir[index];
return true;
}
+
bool GCMemcard::GetFileName(u32 index, char *fn) //index in the directory array
{
if (!mcdFile) return false;
@@ -387,14 +404,13 @@ bool GCMemcard::GetComment2(u32 index, char *fn) //index in the directory array u32 decode5A3(u16 val)
{
const int lut5to8[] = { 0x00,0x08,0x10,0x18,0x20,0x29,0x31,0x39,
- 0x41,0x4A,0x52,0x5A,0x62,0x6A,0x73,0x7B,
- 0x83,0x8B,0x94,0x9C,0xA4,0xAC,0xB4,0xBD,
- 0xC5,0xCD,0xD5,0xDE,0xE6,0xEE,0xF6,0xFF};
+ 0x41,0x4A,0x52,0x5A,0x62,0x6A,0x73,0x7B,
+ 0x83,0x8B,0x94,0x9C,0xA4,0xAC,0xB4,0xBD,
+ 0xC5,0xCD,0xD5,0xDE,0xE6,0xEE,0xF6,0xFF};
const int lut4to8[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
- 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
+ 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
const int lut3to8[] = { 0x00,0x24,0x48,0x6D,0x91,0xB6,0xDA,0xFF};
-
int r,g,b,a;
if ((val&0x8000))
{
@@ -433,11 +449,11 @@ void decode5A3image(u32* dst, u16* src, int width, int height) void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height)
{
- for (int y = 0; y < height; y += 4)
+ for (int y = 0; y < height; y += 4)
{
- for (int x = 0; x < width; x += 8)
+ for (int x = 0; x < width; x += 8)
{
- for (int iy = 0; iy < 4; iy++, src += 8)
+ for (int iy = 0; iy < 4; iy++, src += 8)
{
u32 *tdst = dst+(y+iy)*width+x;
for (int ix = 0; ix < 8; ix++)
@@ -486,7 +502,7 @@ bool GCMemcard::ReadBannerRGBA8(u32 index, u32* buffer) return true;
}
-u32 GCMemcard::ReadAnimRGBA8(u32 index, u32* buffer, u8 *delays)
+u32 GCMemcard::ReadAnimRGBA8(u32 index, u32* buffer, u8 *delays)
{
if (!mcdFile) return 0;
@@ -614,7 +630,7 @@ bool GCMemcard::FixChecksums() hdr.CheckSum1[1] = u8(csum1);
hdr.CheckSum2[0] = u8(csum2 >> 8);
hdr.CheckSum2[1] = u8(csum2);
-
+
calc_checksumsBE((u16*)&dir, 0xFFE, &csum1, &csum2);
dir.CheckSum1[0] = u8(csum1 >> 8);
dir.CheckSum1[1] = u8(csum1);
@@ -641,7 +657,7 @@ bool GCMemcard::FixChecksums() return true;
}
-u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
+u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
{
if (!mcdFile) return NOMEMCARD;
@@ -667,7 +683,7 @@ u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index) return ret;
}
-s32 GCMemcard::ImportGci(const char *fileName, std::string fileName2)
+s32 GCMemcard::ImportGci(const char *fileName, std::string fileName2)
{
if (fileName2.empty() && !mcdFile) return OPENFAIL;
@@ -685,7 +701,7 @@ s32 GCMemcard::ImportGci(const char *fileName, std::string fileName2) {
fread(tmp, 1, 0xD, gci);
if (!strcasecmp(fileType.c_str(), ".gcs"))
- {
+ {
if (!memcmp(tmp, "GCSAVE", 6)) // Header must be uppercase
offset = GCS;
else
@@ -760,7 +776,7 @@ s32 GCMemcard::ImportGci(const char *fileName, std::string fileName2) u32 size = BE16((d->BlockCount)) * 0x2000;
u8 *t = new u8[size];
fread(t, 1, size, gci);
- fclose(gci);
+ fclose(gci);
u32 ret;
if(!fileName2.empty())
{
@@ -805,7 +821,6 @@ u32 GCMemcard::ExportGci(u32 index, const char *fileName) break;
}
-
fseek(gci, 0x40, SEEK_SET);
assert(fwrite(t, 1, 0x2000 * BE16(d.BlockCount), gci)== (unsigned) (0x2000 * BE16(d.BlockCount)));
fclose(gci);
@@ -837,21 +852,62 @@ GCMemcard::GCMemcard(const char *filename) {
FILE *mcd = fopen(filename,"r+b");
mcdFile = mcd;
+ fail[0] = true;
if (!mcd) return;
+ for(int i=0;i<12;i++)fail[i]=false;
+
+ //This function can be removed once more about hdr is known and we can check for a valid header
+ std::string fileType;
+ SplitPath(filename, NULL, NULL, &fileType);
+ if (strcasecmp(fileType.c_str(), ".raw") && strcasecmp(fileType.c_str(), ".gcp"))
+ {
+ fail[0] = true;
+ fail[NOTRAWORGCP] = true;
+ return;
+ }
+
fseek(mcd, 0x0000, SEEK_SET);
- assert(fread(&hdr, 1, 0x2000, mcd) == 0x2000);
- assert(fread(&dir, 1, 0x2000, mcd) == 0x2000);
- assert(fread(&dir_backup, 1, 0x2000, mcd) == 0x2000);
- assert(fread(&bat, 1, 0x2000, mcd) == 0x2000);
- assert(fread(&bat_backup, 1, 0x2000, mcd) == 0x2000);
+ if (fread(&hdr, 1, 0x2000, mcd) != 0x2000)
+ {
+ fail[0] = true;
+ fail[HDR_READ_ERROR] = true;
+ return;
+ }
+ if (fread(&dir, 1, 0x2000, mcd) != 0x2000)
+ {
+ fail[0] = true;
+ fail[DIR_READ_ERROR] = true;
+ return;
+ }
+ if (fread(&dir_backup, 1, 0x2000, mcd) != 0x2000)
+ {
+ fail[0] = true;
+ fail[DIR_BAK_READ_ERROR] = true;
+ return;
+ }
+ if (fread(&bat, 1, 0x2000, mcd) != 0x2000)
+ {
+ fail[0] = true;
+ fail[BAT_READ_ERROR] = true;
+ return;
+ }
+ if (fread(&bat_backup, 1, 0x2000, mcd) != 0x2000)
+ {
+ fail[0] = true;
+ fail[BAT_BAK_READ_ERROR] = true;
+ return;
+ }
u32 csums = TestChecksums();
if (csums&1)
{
// header checksum error!
- // TODO: fail to load
+ // invalid files do not always get here
+ fail[0] = true;
+ fail[HDR_CSUM_FAIL] = true;
+ return;
}
if (csums&2) // directory checksum error!
@@ -859,7 +915,9 @@ GCMemcard::GCMemcard(const char *filename) if (csums&4)
{
// backup is also wrong!
- // TODO: fail to load
+ fail[0] = true;
+ fail[DIR_CSUM_FAIL] = true;
+ return;
}
else
{
@@ -877,7 +935,9 @@ GCMemcard::GCMemcard(const char *filename) if (csums&16)
{
// backup is also wrong!
- // TODO: fail to load
+ fail[0] = true;
+ fail[BAT_CSUM_FAIL] = true;
+ return;
}
else
{
@@ -900,15 +960,30 @@ GCMemcard::GCMemcard(const char *filename) fseek(mcd, 0xa000, SEEK_SET);
- assert(BE16(hdr.Size) != 0xFFFF);
- mc_data_size = (((u32)BE16(hdr.Size) * 16) - 5) * 0x2000;
- mc_data = new u8[mc_data_size];
+ u16 size = BE16(hdr.Size);
+ if ((size== 0x0080) || (size == 0x0040) ||
+ (size == 0x0020) || (size == 0x0010) ||
+ (size == 0x0008) || (size == 0x0004))
+ {
+ mc_data_size = (((u32)size * 16) - 5) * 0x2000;
+ mc_data = new u8[mc_data_size];
- size_t read = fread(mc_data, 1, mc_data_size, mcd);
- assert(mc_data_size == read);
+ size_t read = fread(mc_data, 1, mc_data_size, mcd);
+ if (mc_data_size != read)
+ {
+ fail[0] = true;
+ fail[DATA_READ_FAIL] = true;
+ }
+ }
+ else
+ {
+ fail[0] = true;
+ fail[HDR_SIZE_FFFF] = true;
+ }
}
GCMemcard::~GCMemcard()
{
+ if (!mcdFile) return;
fclose((FILE*)mcdFile);
}
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h index 9f5196e8b0..dc0ee0664f 100644 --- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h @@ -27,6 +27,17 @@ enum SAVFAIL,
OPENFAIL,
GCI,
+ HDR_READ_ERROR,
+ DIR_READ_ERROR,
+ DIR_BAK_READ_ERROR,
+ BAT_READ_ERROR,
+ BAT_BAK_READ_ERROR,
+ HDR_CSUM_FAIL,
+ DIR_CSUM_FAIL,
+ BAT_CSUM_FAIL,
+ DATA_READ_FAIL,
+ HDR_SIZE_FFFF,
+ NOTRAWORGCP,
SAV = 0x80,
GCS = 0x110,
OUTOFBLOCKS,
@@ -38,9 +49,9 @@ enum FAIL
};
-
class GCMemcard
{
+private:
void* mcdFile;
u32 mc_data_size;
@@ -48,8 +59,6 @@ class GCMemcard void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2);
-public:
-
#pragma pack(push,1)
struct OSTime {
u32 low;
@@ -133,6 +142,9 @@ public: } bat,bat_backup;
#pragma pack(pop)
+public:
+ bool fail[12];
+
// constructor
GCMemcard(const char* fileName);
@@ -148,7 +160,7 @@ public: u32 GetNumFiles();
// Returns true if title already on memcard
- bool titlePresent(DEntry d);
+ bool TitlePresent(DEntry d);
// read directory entry
bool GetFileInfo(u32 index, DEntry& data);
@@ -156,6 +168,12 @@ public: // buffer needs to be a char[32] or bigger
bool GetFileName(u32 index, char* buffer);
+ bool GetNumBlocks(u32 index, u16* buffer);
+
+ u16 GetFreeBlocks(void);
+
+ bool GetFirstBlock(u32 index, u16* buffer);
+
// buffer needs to be a char[32] or bigger
bool GetComment1(u32 index, char* buffer);
|
