summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/Core/DolphinWX/Src/MemcardManager.cpp100
-rw-r--r--Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp110
-rw-r--r--Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h14
3 files changed, 167 insertions, 57 deletions
diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp
index 74cd045fd6..971dc64875 100644
--- a/Source/Core/DolphinWX/Src/MemcardManager.cpp
+++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp
@@ -215,17 +215,40 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
case ID_COPYTOLEFT:
if ((index1 != -1) && (memoryCard[0] != NULL))
{
- memoryCard[0]->CopyFrom(*memoryCard[1], index1);
- memoryCard[0]->Save();
- ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
+ switch (memoryCard[0]->CopyFrom(*memoryCard[1], index1))
+ {
+ case FAIL:
+ wxMessageBox(wxT("Invalid bat.map or dir entry"), wxT("Failure"), wxOK);
+ break;
+ case NOMEMCARD:
+ wxMessageBox(wxT("File is not recognized as a memcard"), wxT("Failure"), wxOK);
+ break;
+ case SUCCESS:
+ memoryCard[0]->Save();
+ ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
+ break;
+ }
+
}
break;
case ID_COPYTORIGHT:
if ((index0 != -1) && (memoryCard[1] != NULL))
{
- memoryCard[1]->CopyFrom(*memoryCard[0], index0);
- memoryCard[1]->Save();
- ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1);
+ switch (memoryCard[1]->CopyFrom(*memoryCard[0], index0))
+ {
+ case FAIL:
+ wxMessageBox(wxT("Invalid bat.map or dir entry"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ case NOMEMCARD:
+ wxMessageBox(wxT("File is not recognized as a memcard"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ case SUCCESS:
+ memoryCard[1]->Save();
+ ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1);
+ break;
+ }
}
break;
case ID_FIXCHECKSUM:
@@ -279,39 +302,43 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
break;
case GCSFAIL:
wxMessageBox(wxT("Imported file has gsc extension\nbut"
- " does not have a correct header"), wxT("Error"),
- wxOK|wxICON_ERROR);
+ " does not have a correct header"),
+ wxT("Error"), wxOK|wxICON_ERROR);
break;
case SAVFAIL:
wxMessageBox(wxT("Imported file has sav extension\nbut"
- " does not have a correct header"), wxT("Error"),
- wxOK|wxICON_ERROR);
+ " does not have a correct header"),
+ wxT("Error"), wxOK|wxICON_ERROR);
break;
case OPENFAIL:
wxMessageBox(wxT("Imported file could not be opened\nor"
- " does not have a valid extension"), wxT("Error"),
- wxOK|wxICON_ERROR);
+ " does not have a valid extension"),
+ wxT("Error"), wxOK|wxICON_ERROR);
break;
case GCS:
wxMessageBox(wxT("File converted to .gci"),
- wxT("Success"),wxOK);
+ wxT("Success"), wxOK);
break;
case OUTOFBLOCKS:
freeBlocks = BE16(memoryCard[slot]->bat.FreeBlocks);
blocksOpen.Printf(wxT("Only %d blocks available"), freeBlocks);
- wxMessageBox(blocksOpen,wxT("Failure"),wxOK);
+ wxMessageBox(blocksOpen, wxT("Error"), wxOK|wxICON_ERROR);
break;
case OUTOFDIRENTRIES:
wxMessageBox(wxT("No free dir index entries"),
- wxT("Failure"),wxOK);
+ wxT("Error"), wxOK|wxICON_ERROR);
break;
case NOMEMCARD:
wxMessageBox(wxT("File is not recognized as a memcard"),
- wxT("Failure"),wxOK);
+ wxT("Error"), wxOK|wxICON_ERROR);
break;
case TITLEPRESENT:
wxMessageBox(wxT("Memcard already has a save for this title"),
- wxT("Failure"),wxOK);
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ case FAIL:
+ wxMessageBox(wxT("Invalid bat.map or dir entry"),
+ wxT("Error"), wxOK|wxICON_ERROR);
break;
default:
memoryCard[slot]->Save();
@@ -339,7 +366,26 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
const char * fileName = temp.ToAscii();
if (temp.length() > 0)
- memoryCard[slot]->ExportGci(index2, fileName);
+ {
+ switch (memoryCard[slot]->ExportGci(index2, fileName))
+ {
+ case NOMEMCARD:
+ wxMessageBox(wxT("File is not recognized as a memcard"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ case NOFILE:
+ wxMessageBox(wxT("Could not open gci for writing"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ case FAIL:
+ //TODO: delete file if fails
+ wxMessageBox(wxT("Invalid bat.map or dir entry"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ default:
+ break;
+ }
+ }
}
break;
case ID_DELETELEFT:
@@ -348,10 +394,22 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
case ID_DELETERIGHT:
if (index2 != -1)
{
- memoryCard[slot]->RemoveFile(index2);
- memoryCard[slot]->Save();
- slot == 1 ? ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1)
+ switch (memoryCard[slot]->RemoveFile(index2))
+ {
+ case NOMEMCARD:
+ wxMessageBox(wxT("File is not recognized as a memcard"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ case FAIL:
+ wxMessageBox(wxT("Invalid bat.map or dir entry"),
+ wxT("Error"), wxOK|wxICON_ERROR);
+ break;
+ case SUCCESS:
+ memoryCard[slot]->Save();
+ slot == 1 ? ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1)
: ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0);
+ break;
+ }
}
break;
}
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp
index 2629be2c2a..1efbbd3dfd 100644
--- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp
+++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp
@@ -83,21 +83,40 @@ u32 GCMemcard::GetNumFiles()
return j;
}
-bool GCMemcard::titlePresent(u32 gameCode)
+bool GCMemcard::titlePresent(DEntry d)
{
- if (!mcdFile) return 0;
+ //TODO: Clean up this function
+ bool equal = false;
+ if (!mcdFile) return false;
for (int i = 0; i < 127; i++)
{
- if (BE32(dir.Dir[i].Gamecode) == gameCode)
- return true;
+ if (BE32(dir.Dir[i].Gamecode) == BE32(d.Gamecode))
+ {
+ for ( int j = 0; j < 32; j++)
+ {
+ if (dir.Dir[i].Filename[j] != d.Filename[j])
+ {
+ equal = false;
+ break;
+ }
+ else
+ {
+ equal = true;
+ }
+ }
+ if (equal)
+ {
+ return true;
+ }
+ }
}
return false;
}
-bool GCMemcard::RemoveFile(u32 index) //index in the directory array
+u32 GCMemcard::RemoveFile(u32 index) //index in the directory array
{
- if (!mcdFile) return false;
+ if (!mcdFile) return NOMEMCARD;
//backup the directory and bat (not really needed here but meh :P
dir_backup = dir;
@@ -124,9 +143,14 @@ bool GCMemcard::RemoveFile(u32 index) //index in the directory array
bat.FreeBlocks[0] = u8(freeBlock >> 8);
bat.FreeBlocks[1] = u8(freeBlock);
t = new u8[GetFileSize(i) * 0x2000];
- if (!GetFileData(i, t, true))
+ switch (GetFileData(i, t, true))
{
+ case NOMEMCARD:
delete[] t;
+ break;
+ case FAIL:
+ return FAIL;
+ break;
}
}
memset(&(dir.Dir[i]), 0xFF, 0x40);
@@ -157,7 +181,7 @@ bool GCMemcard::RemoveFile(u32 index) //index in the directory array
FixChecksums();
Save();
- return true;
+ return SUCCESS;
}
u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
@@ -172,7 +196,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
{
return OUTOFBLOCKS;
}
- if (!remove && titlePresent(BE32(direntry.Gamecode))) 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);
@@ -265,38 +289,43 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
return fileBlocks;
}
-bool GCMemcard::GetFileData(u32 index, u8*dest, bool old) //index in the directory array
+u32 GCMemcard::GetFileData(u32 index, u8*dest, bool old) //index in the directory array
{
- if (!mcdFile) return false;
+ if (!mcdFile) return NOMEMCARD;
+
+ int block = BE16(dir.Dir[index].FirstBlock);
+ int saveLength = BE16(dir.Dir[index].BlockCount);
+ int memcardSize = BE16(hdr.Size) * 0x0010;
+
+ if (block + saveLength > memcardSize)
+ {
+ return FAIL;
+ }
if (!old)
{
- int block = BE16(dir.Dir[index].FirstBlock);
- int saveLength = BE16(dir.Dir[index].BlockCount) * 2000;
- memcpy(dest,mc_data + 0x2000*(block-5), saveLength);
+ memcpy(dest,mc_data + 0x2000*(block-5), saveLength*0x2000);
}
else
{
- int block = BE16(dir.Dir[index].FirstBlock);
- int saveLength = BE16(dir.Dir[index].BlockCount);
- int memcardSize = BE16(hdr.Size) * 0x0010;
- assert(block != 0xFFFF);
- assert(block > 0);
+ assert(block != 0xFFFF);
+ assert(block > 0);
do
{
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;
+
+ 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);
}
- return true;
+ return SUCCESS;
}
u32 GCMemcard::GetFileSize(u32 index) //index in the directory array
@@ -614,14 +643,23 @@ bool GCMemcard::FixChecksums()
}
u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index)
{
- if (!mcdFile) return 0;
+ if (!mcdFile) return NOMEMCARD;
DEntry d;
if (!source.GetFileInfo(index, d)) return 0;
u8 *t = new u8[source.GetFileSize(index) * 0x2000];
- if(!source.GetFileData(index, t, true)) return 0;
+ switch (source.GetFileData(index, t, true))
+ {
+ case FAIL:
+ return FAIL;
+ case NOMEMCARD:
+ return NOMEMCARD;
+ default:
+ break;
+ }
+
u32 ret = ImportFile(d,t,0);
delete[] t;
@@ -745,24 +783,34 @@ s32 GCMemcard::ImportGci(const char *fileName, std::string fileName2)
return ret;
}
-bool GCMemcard::ExportGci(u32 index, const char *fileName)
+u32 GCMemcard::ExportGci(u32 index, const char *fileName)
{
FILE *gci = fopen(fileName, "wb");
- if (!gci) return false;
+ if (!gci) return NOFILE;
fseek(gci, 0, SEEK_SET);
DEntry d;
- if (!this->GetFileInfo(index, d)) return false;
+ if (!this->GetFileInfo(index, d)) return NOMEMCARD;
assert(fwrite(&d, 1, 0x40, gci) == 0x40);
u8 *t = new u8[this->GetFileSize(index) * 0x2000];
- if (!this->GetFileData(index, t, true)) return false;
+
+ switch(GetFileData(index, t, true))
+ {
+ case FAIL:
+ return FAIL;
+ case NOMEMCARD:
+ return NOMEMCARD;
+ default:
+ break;
+ }
+
fseek(gci, 0x40, SEEK_SET);
assert(fwrite(t, 1, 0x2000 * BE16(d.BlockCount), gci)== (unsigned) (0x2000 * BE16(d.BlockCount)));
fclose(gci);
delete []t;
- return true;
+ return SUCCESS;
}
bool GCMemcard::Save()
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h
index ecde3a233d..9f5196e8b0 100644
--- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h
+++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h
@@ -32,9 +32,13 @@ enum
OUTOFBLOCKS,
OUTOFDIRENTRIES,
NOMEMCARD,
- TITLEPRESENT
+ NOFILE,
+ TITLEPRESENT,
+ SUCCESS = 0x2000,
+ FAIL
};
+
class GCMemcard
{
void* mcdFile;
@@ -144,7 +148,7 @@ public:
u32 GetNumFiles();
// Returns true if title already on memcard
- bool titlePresent(u32 gameCode);
+ bool titlePresent(DEntry d);
// read directory entry
bool GetFileInfo(u32 index, DEntry& data);
@@ -165,10 +169,10 @@ public:
// old determines if function uses old or new method of copying data
// some functions only work with old way, some only work with new way
// TODO: find a function that works for all calls or split into 2 functions
- bool GetFileData(u32 index, u8* buffer, bool old);
+ u32 GetFileData(u32 index, u8* buffer, bool old);
// delete a file from the directory
- bool RemoveFile(u32 index);
+ u32 RemoveFile(u32 index);
// adds the file to the directory and copies its contents
// if remove > 0 it will pad bat.map with 0's sifeof remove
@@ -178,7 +182,7 @@ public:
u32 CopyFrom(GCMemcard& source, u32 index);
// writes a .gci file to disk containing index
- bool ExportGci(u32 index, const char* fileName);
+ u32 ExportGci(u32 index, const char* fileName);
// reads a .gci/.gcs/.sav file and calls ImportFile or saves out a gci file
s32 ImportGci(const char* fileName, std::string fileName2);