diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt
index b5e731ce15..734d966781 100644
--- a/Source/Core/Core/CMakeLists.txt
+++ b/Source/Core/Core/CMakeLists.txt
@@ -101,6 +101,7 @@ set(SRCS Src/ActionReplay.cpp
Src/HW/EXI_DeviceIPL.cpp
Src/HW/EXI_DeviceMemoryCard.cpp
Src/HW/EXI_DeviceMic.cpp
+ Src/HW/GCMemcard.cpp
Src/HW/GCPad.cpp
Src/HW/GCPadEmu.cpp
Src/HW/GPFifo.cpp
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index cc6d673f29..b0b72fcc1b 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -287,6 +287,7 @@
+
@@ -483,6 +484,7 @@
+
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index e51098f2ec..66b25af176 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -553,6 +553,9 @@
FifoPlayer
+
+ HW %28Flipper/Hollywood%29\GCMemcard
+
@@ -1027,6 +1030,9 @@
FifoPlayer
+
+ HW %28Flipper/Hollywood%29\GCMemcard
+
@@ -1165,5 +1171,8 @@
{ca7d56f7-4e84-4d15-9aea-7ae6fa7d6586}
+
+ {3e9e6e83-c1bf-45f9-aeff-231f98f60d29}
+
\ No newline at end of file
diff --git a/Source/Core/Core/SConscript b/Source/Core/Core/SConscript
index 2f350557ec..3dafad8a62 100644
--- a/Source/Core/Core/SConscript
+++ b/Source/Core/Core/SConscript
@@ -97,6 +97,7 @@ files = [
'Src/HW/EXI_DeviceIPL.cpp',
'Src/HW/EXI_DeviceMemoryCard.cpp',
'Src/HW/EXI_DeviceMic.cpp',
+ 'Src/HW/GCMemcard.cpp',
'Src/HW/GCPad.cpp',
'Src/HW/GCPadEmu.cpp',
'Src/HW/GPFifo.cpp',
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
index 341a14bec6..5e3d6865d4 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
+++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp
@@ -26,6 +26,7 @@
#include "EXI_Device.h"
#include "EXI_DeviceMemoryCard.h"
#include "Sram.h"
+#include "GCMemcard.h"
#define MC_STATUS_BUSY 0x80
#define MC_STATUS_UNLOCKED 0x40
@@ -34,6 +35,7 @@
#define MC_STATUS_PROGRAMEERROR 0x08
#define MC_STATUS_READY 0x01
#define SIZE_TO_Mb (1024 * 8 * 16)
+#define MC_HDR_SIZE 0xA000
static CEXIMemoryCard *cards[2];
@@ -84,7 +86,6 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
INFO_LOG(EXPANSIONINTERFACE, "Reading memory card %s", m_strFilename.c_str());
pFile.ReadBytes(memory_card_content, memory_card_size);
- SetCardFlashID(memory_card_content, card_index);
}
else
@@ -94,11 +95,11 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
memory_card_size = nintendo_card_id * SIZE_TO_Mb;
memory_card_content = new u8[memory_card_size];
- memset(memory_card_content, 0xFF, memory_card_size);
-
+ GCMemcard::Format(memory_card_content, m_strFilename.find(".JAP.raw") != std::string::npos, nintendo_card_id);
+ memset(memory_card_content+MC_HDR_SIZE, 0xFF, memory_card_size-MC_HDR_SIZE);
WARN_LOG(EXPANSIONINTERFACE, "No memory card found. Will create new.");
- Flush();
}
+ SetCardFlashID(memory_card_content, card_index);
}
void innerFlush(FlushData* data)
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp b/Source/Core/Core/Src/HW/GCMemcard.cpp
similarity index 81%
rename from Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp
rename to Source/Core/Core/Src/HW/GCMemcard.cpp
index df79e001f2..2471e76599 100644
--- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp
+++ b/Source/Core/Core/Src/HW/GCMemcard.cpp
@@ -61,7 +61,10 @@ void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height)
}
}
-GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) : m_valid(false), m_fileName(filename)
+GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis)
+ : m_valid(false)
+ , m_fileName(filename)
+ , mc_data(NULL)
{
File::IOFile mcdFile(m_fileName, "r+b");
if (!mcdFile.IsOpen())
@@ -71,10 +74,7 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) : m_va
return;
}
Format(forceCreation ? sjis : !AskYesNoT("Format as ascii (NTSC\\PAL)?\nChoose no for sjis (NTSC-J)"));
- if (!mcdFile.Open(m_fileName, "r+b"))
- {
- return;
- }
+ return;
}
else
{
@@ -227,7 +227,7 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) : m_va
bool GCMemcard::IsAsciiEncoding()
{
- return hdr.Encoding[1] == 0;
+ return hdr.Encoding == 0;
}
bool GCMemcard::Save()
@@ -245,51 +245,49 @@ bool GCMemcard::Save()
return mcdFile.Close();
}
-void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2)
+void GCMemcard::calc_checksumsBE(u16 *buf, u32 length, u16 *csum, u16 *inv_csum)
{
- *c1 = 0;*c2 = 0;
- for (u32 i = 0; i < num; ++i)
+ *csum = *inv_csum = 0;
+
+ for (u32 i = 0; i < length; ++i)
{
//weird warnings here
- *c1 += Common::swap16(buf[i]);
- *c2 += Common::swap16((u16)(buf[i] ^ 0xffff));
+ *csum += BE16(buf[i]);
+ *inv_csum += BE16((u16)(buf[i] ^ 0xffff));
}
- if (*c1 == 0xffff)
+ *csum = BE16(*csum);
+ *inv_csum = BE16(*inv_csum);
+ if (*csum == 0xffff)
{
- *c1 = 0;
+ *csum = 0;
}
- if (*c2 == 0xffff)
+ if (*inv_csum == 0xffff)
{
- *c2 = 0;
+ *inv_csum = 0;
}
}
u32 GCMemcard::TestChecksums()
{
- u16 csum1=0,
- csum2=0;
+ u16 csum=0,
+ csum_inv=0;
u32 results = 0;
- calc_checksumsBE((u16*)&hdr, 0xFE , &csum1, &csum2);
- if (BE16(hdr.CheckSum1) != csum1) results |= 1;
- if (BE16(hdr.CheckSum2) != csum2) results |= 1;
+ calc_checksumsBE((u16*)&hdr, 0xFE , &csum, &csum_inv);
+ if ((hdr.Checksum != csum) || (hdr.Checksum_Inv != csum_inv)) results |= 1;
- calc_checksumsBE((u16*)&dir, 0xFFE, &csum1, &csum2);
- if (BE16(dir.CheckSum1) != csum1) results |= 2;
- if (BE16(dir.CheckSum2) != csum2) results |= 2;
+ calc_checksumsBE((u16*)&dir, 0xFFE, &csum, &csum_inv);
+ if ((dir.Checksum != csum) || (dir.Checksum_Inv != csum_inv)) results |= 2;
- calc_checksumsBE((u16*)&dir_backup, 0xFFE, &csum1, &csum2);
- if (BE16(dir_backup.CheckSum1) != csum1) results |= 4;
- if (BE16(dir_backup.CheckSum2) != csum2) results |= 4;
+ calc_checksumsBE((u16*)&dir_backup, 0xFFE, &csum, &csum_inv);
+ if ((dir_backup.Checksum != csum) || (dir_backup.Checksum_Inv != csum_inv)) results |= 4;
- calc_checksumsBE((u16*)(((u8*)&bat)+4), 0xFFE, &csum1, &csum2);
- if (BE16(bat.CheckSum1) != csum1) results |= 8;
- if (BE16(bat.CheckSum2) != csum2) results |= 8;
+ calc_checksumsBE((u16*)(((u8*)&bat)+4), 0xFFE, &csum, &csum_inv);
+ if ((bat.Checksum != csum) || (bat.Checksum_Inv != csum_inv)) results |= 8;
- calc_checksumsBE((u16*)(((u8*)&bat_backup)+4), 0xFFE, &csum1, &csum2);
- if (BE16(bat_backup.CheckSum1) != csum1) results |= 16;
- if (BE16(bat_backup.CheckSum2) != csum2) results |= 16;
+ calc_checksumsBE((u16*)(((u8*)&bat_backup)+4), 0xFFE, &csum, &csum_inv);
+ if ((bat_backup.Checksum != csum) || (bat_backup.Checksum_Inv != csum_inv)) results |= 16;
return results;
}
@@ -298,39 +296,12 @@ bool GCMemcard::FixChecksums()
{
if (!m_valid)
return false;
-
- u16 csum1=0,
- csum2=0;
-
- calc_checksumsBE((u16*)&hdr, 0xFE, &csum1, &csum2);
- hdr.CheckSum1[0] = u8(csum1 >> 8);
- 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);
- dir.CheckSum2[0] = u8(csum2 >> 8);
- dir.CheckSum2[1] = u8(csum2);
-
- calc_checksumsBE((u16*)&dir_backup, 0xFFE, &csum1, &csum2);
- dir_backup.CheckSum1[0] = u8(csum1 >> 8);
- dir_backup.CheckSum1[1] = u8(csum1);
- dir_backup.CheckSum2[0] = u8(csum2 >> 8);
- dir_backup.CheckSum2[1] = u8(csum2);
-
- calc_checksumsBE((u16*)(((u8*)&bat)+4), 0xFFE, &csum1, &csum2);
- bat.CheckSum1[0] = u8(csum1 >> 8);
- bat.CheckSum1[1] = u8(csum1);
- bat.CheckSum2[0] = u8(csum2 >> 8);
- bat.CheckSum2[1] = u8(csum2);
-
- calc_checksumsBE((u16*)(((u8*)&bat_backup)+4), 0xFFE, &csum1, &csum2);
- bat_backup.CheckSum1[0] = u8(csum1 >> 8);
- bat_backup.CheckSum1[1] = u8(csum1);
- bat_backup.CheckSum2[0] = u8(csum2 >> 8);
- bat_backup.CheckSum2[1] = u8(csum2);
+
+ calc_checksumsBE((u16*)&hdr, 0xFE, &hdr.Checksum, &hdr.Checksum_Inv);
+ calc_checksumsBE((u16*)&dir, 0xFFE, &dir.Checksum, &dir.Checksum_Inv);
+ calc_checksumsBE((u16*)&dir_backup, 0xFFE, &dir_backup.Checksum, &dir_backup.Checksum_Inv);
+ calc_checksumsBE((u16*)&bat+2, 0xFFE, &bat.Checksum, &bat.Checksum_Inv);
+ calc_checksumsBE((u16*)&bat_backup+2, 0xFFE, &bat_backup.Checksum, &bat_backup.Checksum_Inv);
return true;
}
@@ -620,8 +591,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
{
index = i;
dir.Dir[i] = direntry;
- dir.Dir[i].FirstBlock[0] = u8(firstFree1 >> 8);
- dir.Dir[i].FirstBlock[1] = u8(firstFree1);
+ *(u16*)&dir.Dir[i].FirstBlock = BE16(firstFree1);
if (!remove)
{
dir.Dir[i].CopyCounter = dir.Dir[i].CopyCounter+1;
@@ -642,7 +612,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
int j = 2;
while(j < BE16(direntry.BlockCount) + 1)
{
- bat_backup.Map[i] = Common::swap16(last + (u16)j);
+ bat_backup.Map[i] = BE16(last + (u16)j);
i++;
j++;
}
@@ -654,25 +624,16 @@ u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents, int remove)
}
//update last allocated block
- int lastallocated = BE16(bat_backup.LastAllocated) + j - 1;
- bat_backup.LastAllocated[0] = u8(lastallocated >> 8);
- bat_backup.LastAllocated[1] = u8(lastallocated);
-
+ *(u16*)&bat_backup.LastAllocated = BE16(BE16(bat_backup.LastAllocated) + j - 1);
//update freespace counter
- int freespace1 = totalspace - firstFree1 - fileBlocks + MC_FST_BLOCKS;
- bat_backup.FreeBlocks[0] = u8(freespace1 >> 8);
- bat_backup.FreeBlocks[1] = u8(freespace1);
+ *(u16*)&bat_backup.FreeBlocks = BE16(totalspace - firstFree1 - fileBlocks + MC_FST_BLOCKS);
if (!remove)
{ // ... and dir update counter
- int updateCtr = BE16(dir_backup.UpdateCounter) + 1;
- dir_backup.UpdateCounter[0] = u8(updateCtr >> 8);
- dir_backup.UpdateCounter[1] = u8(updateCtr);
+ *(u16*)&dir_backup.UpdateCounter = BE16(BE16(dir_backup.UpdateCounter) + 1);
// ... and bat update counter
- updateCtr = BE16(bat_backup.UpdateCounter) + 1;
- bat_backup.UpdateCounter[0] = u8(updateCtr >> 8);
- bat_backup.UpdateCounter[1] = u8(updateCtr);
+ *(u16*)&bat_backup.UpdateCounter = BE16(BE16(bat_backup.UpdateCounter) + 1);
}
bat = bat_backup;
return SUCCESS;
@@ -698,9 +659,7 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array
//free the blocks
int blocks_left = BE16(dir.Dir[index].BlockCount);
- int block = BE16(dir.Dir[index].FirstBlock) - 1;
- bat.LastAllocated[0] = (u8)(block >> 8);
- bat.LastAllocated[1] = (u8)block;
+ *(u16*)&bat.LastAllocated = BE16(BE16(dir.Dir[index].FirstBlock) - 1);
u8 nextIndex = index + 1;
memset(&(dir.Dir[index]), 0xFF, DENTRY_SIZE);
@@ -713,9 +672,7 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array
//Only get file data if it is a valid dir entry
if (BE16(tempDEntry->FirstBlock) != 0xFFFF)
{
- u16 freeBlock= BE16(bat.FreeBlocks) - BE16(tempDEntry->BlockCount);
- bat.FreeBlocks[0] = u8(freeBlock >> 8);
- bat.FreeBlocks[1] = u8(freeBlock);
+ *(u16*)&bat.FreeBlocks = BE16(BE16(bat.FreeBlocks) - BE16(tempDEntry->BlockCount));
u16 size = DEntry_BlockCount(nextIndex);
if (size != 0xFFFF)
@@ -754,9 +711,7 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array
}
}
// increment update counter
- int updateCtr = BE16(dir.UpdateCounter) + 1;
- dir.UpdateCounter[0] = u8(updateCtr >> 8);
- dir.UpdateCounter[1] = u8(updateCtr);
+ *(u16*)&dir.UpdateCounter = BE16(BE16(dir.UpdateCounter) + 1);
return SUCCESS;
}
@@ -989,9 +944,7 @@ void GCMemcard::Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length)
// It is stored only within the corresponding GSV file.
// If the GCS file is added without using the GameSaves software,
// the value stored is always "1"
- int blockCount = length / BLOCK_SIZE;
- tempDEntry->BlockCount[0] = u8(blockCount >> 8);
- tempDEntry->BlockCount[1] = u8(blockCount);
+ *(u16*)&tempDEntry->BlockCount = BE16(length / BLOCK_SIZE);
}
break;
case SAV:
@@ -1157,70 +1110,97 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays)
return frames;
}
-bool GCMemcard::Format(bool sjis, bool New, int slot, u16 SizeMb, bool hdrOnly)
+
+bool GCMemcard::Format(u8 * card_data, bool sjis, u16 SizeMb)
{
- // Currently only formats cards for slot A
- const u32 data_size = BLOCK_SIZE * (SizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS);
+ if (!card_data)
+ return false;
+ memset(card_data, 0xFF, BLOCK_SIZE*3);
+ memset(card_data + BLOCK_SIZE*3, 0, BLOCK_SIZE*2);
- SRAM m_SRAM;
+ GCMC_Header gcp;
+ gcp.hdr = (Header*)card_data;
+ gcp.dir = (Directory *)(card_data + BLOCK_SIZE);
+ gcp.dir_backup = (Directory *)(card_data + BLOCK_SIZE*2);
+ gcp.bat = (BlockAlloc *)(card_data + BLOCK_SIZE*3);
+ gcp.bat_backup = (BlockAlloc *)(card_data + BLOCK_SIZE*4);
- if (New)
- {
- mc_data_size = data_size;
- mc_data = new u8[mc_data_size];
- }
- // Only Format 16MB memcards for now
- if ((SizeMb != MemCard2043Mb) || (data_size != mc_data_size)) return false;
+ *(u16*)gcp.hdr->SizeMb = BE16(SizeMb);
+ *(u16*)gcp.hdr->Encoding = BE16(sjis ? 1 : 0);
- File::IOFile pStream(File::GetUserPath(F_GCSRAM_IDX), "rb");
- if (pStream)
- {
- pStream.ReadBytes(&m_SRAM, 64);
- pStream.Close();
- }
- else
- {
- m_SRAM = sram_dump;
- }
-
- const u64 time = CEXIIPL::GetGCTime();
- u64 rand = Common::swap64(time);
+ FormatInternal(gcp);
+ return true;
+}
+bool GCMemcard::Format(bool sjis, u16 SizeMb)
+{
memset(&hdr, 0xFF, BLOCK_SIZE);
+ memset(&dir, 0xFF, BLOCK_SIZE);
+ memset(&dir_backup, 0xFF, BLOCK_SIZE);
+ memset(&bat, 0, BLOCK_SIZE);
+ memset(&bat_backup, 0, BLOCK_SIZE);
+
+ GCMC_Header gcp;
+ gcp.hdr = &hdr;
+ gcp.dir = &dir;
+ gcp.dir_backup = &dir_backup;
+ gcp.bat = &bat;
+ gcp.bat_backup = &bat_backup;
+
+ *(u16*)hdr.SizeMb = BE16(SizeMb);
+ *(u16*)hdr.Encoding = BE16(sjis ? 1 : 0);
+ FormatInternal(gcp);
+
+ m_sizeMb = SizeMb;
+ maxBlock = (u32)m_sizeMb * MBIT_TO_BLOCKS;
+ if (mc_data)
+ {
+ delete mc_data;
+ mc_data = NULL;
+ }
+ mc_data_size = BLOCK_SIZE * (m_sizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS);
+ mc_data = new u8[mc_data_size];
+ if (!mc_data)
+ return false;
+
+ memset(mc_data, 0xFF, mc_data_size);
+ m_valid = true;
+
+ return Save();
+}
+
+void GCMemcard::FormatInternal(GCMC_Header &GCP)
+{
+ Header *p_hdr = GCP.hdr;
+ u64 rand = CEXIIPL::GetGCTime();
+ p_hdr->formatTime = Common::swap64(rand);
+
for(int i = 0; i < 12; i++)
{
rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16);
- hdr.serial[i] = (u8)(m_SRAM.flash_id[slot][i] + (u32)rand);
+ p_hdr->serial[i] = (u8)(g_SRAM.flash_id[0][i] + (u32)rand);
rand = (((rand * (u64)0x0000000041c64e6dULL) + (u64)0x0000000000003039ULL) >> 16);
rand &= (u64)0x0000000000007fffULL;
}
+ *(u32*)&p_hdr->SramBias = g_SRAM.counter_bias;
+ *(u32*)&p_hdr->SramLang = g_SRAM.lang;
+ // TODO: determine the purpose of Unk2 1 works for slot A, 0 works for both slot A and slot B
+ *(u32*)&p_hdr->Unk2 = 0; // = _viReg[55]; static vu16* const _viReg = (u16*)0xCC002000;
+ *(u16*)&p_hdr->deviceID = 0;
+ calc_checksumsBE((u16*)p_hdr, 0xFE, &p_hdr->Checksum, &p_hdr->Checksum_Inv);
- hdr.fmtTime.high = (time >> 32) & 0xFFFFFFFF;
- hdr.fmtTime.low = time & 0xFFFFFFFF;
- *(u32*)&(hdr.SramBias) = m_SRAM.counter_bias;
- *(u32*)&(hdr.SramLang) = m_SRAM.lang;
- *(u32*)&(hdr.Unk2) = Common::swap32(1); // = _viReg[55]; static vu16* const _viReg = (u16*)0xCC002000;
- // TODO: find out why memcard cares if component cable used for now set to one like main app
- *(u16*)&(hdr.deviceID) = 0;
- *(u16*)&(hdr.SizeMb) = Common::swap16(SizeMb);
- *(u16*)&(hdr.Encoding) = Common::swap16(sjis ? 1 : 0);
-
- if (!hdrOnly)
- {
- memset(&dir, 0xFF, BLOCK_SIZE);
- memset(&dir_backup, 0xFF, BLOCK_SIZE);
- *(u16*)&dir.UpdateCounter = 0;
- *(u16*)&dir_backup.UpdateCounter = Common::swap16(1);
- memset(&bat, 0, BLOCK_SIZE);
- memset(&bat_backup, 0, BLOCK_SIZE);
- *(u16*)&bat.UpdateCounter = 0;
- *(u16*)&bat_backup.UpdateCounter = Common::swap16(1);
- *(u16*)&bat.FreeBlocks = *(u16*)&bat_backup.FreeBlocks = Common::swap16(SizeMb * MBIT_TO_BLOCKS - MC_FST_BLOCKS);
- *(u16*)&bat.LastAllocated = *(u16*)&bat_backup.LastAllocated = Common::swap16(4);
- memset(mc_data, 0xFF, mc_data_size);
- }
+ Directory *p_dir = GCP.dir,
+ *p_dir_backup = GCP.dir_backup;
+ *(u16*)&p_dir->UpdateCounter = 0;
+ *(u16*)&p_dir_backup->UpdateCounter = BE16(1);
+ calc_checksumsBE((u16*)p_dir, 0xFFE, &p_dir->Checksum, &p_dir->Checksum_Inv);
+ calc_checksumsBE((u16*)p_dir_backup, 0xFFE, &p_dir_backup->Checksum, &p_dir_backup->Checksum_Inv);
- FixChecksums();
- Save();
- return true;
+ BlockAlloc *p_bat = GCP.bat,
+ *p_bat_backup = GCP.bat_backup;
+ *(u16*)&p_bat_backup->UpdateCounter = BE16(1);
+ *(u16*)&p_bat->FreeBlocks = *(u16*)&p_bat_backup->FreeBlocks = BE16(( BE16(p_hdr->SizeMb) * MBIT_TO_BLOCKS) - MC_FST_BLOCKS);
+ *(u16*)&p_bat->LastAllocated = *(u16*)&p_bat_backup->LastAllocated = BE16(4);
+ calc_checksumsBE((u16*)p_bat+2, 0xFFE, &p_bat->Checksum, &p_bat->Checksum_Inv);
+ calc_checksumsBE((u16*)p_bat_backup+2, 0xFFE, &p_bat_backup->Checksum, &p_bat_backup->Checksum_Inv);
}
diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h b/Source/Core/Core/Src/HW/GCMemcard.h
similarity index 89%
rename from Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h
rename to Source/Core/Core/Src/HW/GCMemcard.h
index 07ce5656f8..5aa0a3c97f 100644
--- a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h
+++ b/Source/Core/Core/Src/HW/GCMemcard.h
@@ -19,12 +19,12 @@
#define __GCMEMCARD_h__
#include "Common.h"
-#include "../../../Core/Src/HW/Sram.h"
+#include "Sram.h"
#include "StringUtil.h"
-#include "../../../Core/Src/HW/EXI_DeviceIPL.h"
+#include "EXI_DeviceIPL.h"
-#define BE32(x) ((u32((x)[0])<<24) | (u32((x)[1])<<16) | (u32((x)[2])<<8) | u32((x)[3]))
-#define BE16(x) ((u16((x)[0])<<8) | u16((x)[1]))
+#define BE32(x) (Common::swap32(x))
+#define BE16(x) (Common::swap16(x))
#define ArrayByteSwap(a) (ByteSwap(a, a+sizeof(u8)));
enum
@@ -67,7 +67,7 @@ enum
CI8,
};
-class GCMemcard
+class GCMemcard : NonCopyable
{
private:
friend class CMemcardManagerDebug;
@@ -81,15 +81,10 @@ private:
u16 m_sizeMb;
#pragma pack(push,1)
- struct OSTime {
- u32 low;
- u32 high;
- };
-
struct Header { //Offset Size Description
// Serial in libogc
u8 serial[12]; //0x0000 12 ?
- OSTime fmtTime; //0x000c 8 time of format (OSTime value)
+ u64 formatTime; //0x000c 8 time of format (OSTime value)
u8 SramBias[4]; //0x0014 4 sram bias at time of format
u8 SramLang[4]; //0x0018 4 sram language
u8 Unk2[4]; //0x001c 4 ? almost always 0
@@ -99,8 +94,8 @@ private:
u8 Encoding[2]; //0x0024 2 encoding (ASCII or japanese)
u8 Unused1[468]; //0x0026 468 unused (0xff)
u8 UpdateCounter[2];//0x01fa 2 update Counter (?, probably unused)
- u8 CheckSum1[2]; //0x01fc 2 Checksum 1 (?)
- u8 CheckSum2[2]; //0x01fe 2 Checksum 2 (?)
+ u16 Checksum; //0x01fc 2 Additive Checksum
+ u16 Checksum_Inv; //0x01fe 2 Inverse Checksum
u8 Unused2[7680]; //0x0200 0x1e00 unused (0xff)
} hdr;
@@ -153,31 +148,38 @@ private:
DEntry Dir[DIRLEN]; //0x0000 Directory Entries (max 127)
u8 Padding[0x3a];
u8 UpdateCounter[2];//0x1ffa 2 update Counter
- u8 CheckSum1[2]; //0x1ffc 2 Checksum 1
- u8 CheckSum2[2]; //0x1ffe 2 Checksum 2
+ u16 Checksum; //0x1ffc 2 Additive Checksum
+ u16 Checksum_Inv; //0x1ffe 2 Inverse Checksum
} dir, dir_backup;
struct BlockAlloc {
- u8 CheckSum1[2]; //0x0000 2 Checksum 1
- u8 CheckSum2[2]; //0x0002 2 Checksum 2
+ u16 Checksum; //0x0000 2 Additive Checksum
+ u16 Checksum_Inv; //0x0002 2 Inverse Checksum
u8 UpdateCounter[2];//0x0004 2 update Counter
u8 FreeBlocks[2]; //0x0006 2 free Blocks
u8 LastAllocated[2];//0x0008 2 last allocated Block
u16 Map[0xFFB]; //0x000a 0x1ff8 Map of allocated Blocks
} bat,bat_backup;
+ struct GCMC_Header
+ {
+ Header *hdr;
+ Directory *dir, *dir_backup;
+ BlockAlloc *bat, *bat_backup;
+ };
#pragma pack(pop)
u32 ImportGciInternal(FILE* gcih, const char *inputFile, std::string outputFile);
-
+ static void FormatInternal(GCMC_Header &GCP);
public:
GCMemcard(const char* fileName, bool forceCreation=false, bool sjis=false);
bool IsValid() { return m_valid; }
bool IsAsciiEncoding();
bool Save();
- bool Format(bool sjis = false, bool New = true, int slot = 0, u16 SizeMb = MemCard2043Mb, bool hdrOnly = false);
+ bool Format(bool sjis = false, u16 SizeMb = MemCard2043Mb);
+ static bool Format(u8 * card_data, bool sjis = false, u16 SizeMb = MemCard2043Mb);
- void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2);
+ static void calc_checksumsBE(u16 *buf, u32 length, u16 *csum, u16 *inv_csum);
u32 TestChecksums();
bool FixChecksums();
diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt
index f38e791cd0..438ee9ce82 100644
--- a/Source/Core/DolphinWX/CMakeLists.txt
+++ b/Source/Core/DolphinWX/CMakeLists.txt
@@ -52,7 +52,6 @@ if(wxWidgets_FOUND)
Src/LogWindow.cpp
Src/Main.cpp
Src/MemcardManager.cpp
- Src/MemoryCards/GCMemcard.cpp
Src/MemoryCards/WiiSaveCrypted.cpp
Src/NetWindow.cpp
Src/PHackSettings.cpp
diff --git a/Source/Core/DolphinWX/Dolphin.vcxproj b/Source/Core/DolphinWX/Dolphin.vcxproj
index fc232ea77f..2d64eb58bc 100644
--- a/Source/Core/DolphinWX/Dolphin.vcxproj
+++ b/Source/Core/DolphinWX/Dolphin.vcxproj
@@ -255,7 +255,6 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
true
-
@@ -309,7 +308,6 @@ xcopy "$(SolutionDir)..\Externals\SDL\$(PlatformName)\*.dll" "$(TargetDir)" /e /
-
diff --git a/Source/Core/DolphinWX/Dolphin.vcxproj.filters b/Source/Core/DolphinWX/Dolphin.vcxproj.filters
index 3c14226fc0..9c679eee36 100644
--- a/Source/Core/DolphinWX/Dolphin.vcxproj.filters
+++ b/Source/Core/DolphinWX/Dolphin.vcxproj.filters
@@ -6,9 +6,6 @@
-
- GUI\Saves
-
GUI\Saves
@@ -141,9 +138,6 @@
-
- GUI\Saves
-
GUI\Saves
diff --git a/Source/Core/DolphinWX/SConscript b/Source/Core/DolphinWX/SConscript
index 3d3d1e56c2..92ca4f9f62 100644
--- a/Source/Core/DolphinWX/SConscript
+++ b/Source/Core/DolphinWX/SConscript
@@ -43,7 +43,6 @@ else:
'Src/LogWindow.cpp',
'Src/Main.cpp',
'Src/MemcardManager.cpp',
- 'Src/MemoryCards/GCMemcard.cpp',
'Src/MemoryCards/WiiSaveCrypted.cpp',
'Src/NetWindow.cpp',
'Src/PHackSettings.cpp',
diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp
index 8b2dcb07f6..10472b15eb 100644
--- a/Source/Core/DolphinWX/Src/ConfigMain.cpp
+++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp
@@ -27,6 +27,7 @@
#include "HW/SI.h"
#include "HW/DSPHLE/DSPHLE.h"
#include "HW/DSPLLE/DSPLLE.h"
+#include "HW/GCMemcard.h"
#include "IPC_HLE/WII_IPC_HLE.h"
#include "NANDContentLoader.h"
@@ -37,7 +38,6 @@
#include "Frame.h"
#include "HotkeyDlg.h"
#include "Main.h"
-#include "MemoryCards/GCMemcard.h"
#include "VideoBackendBase.h"
#define TEXT_BOX(page, text) new wxStaticText(page, wxID_ANY, text, wxDefaultPosition, wxDefaultSize)
diff --git a/Source/Core/DolphinWX/Src/MemcardManager.h b/Source/Core/DolphinWX/Src/MemcardManager.h
index e3707f6414..beff71b671 100644
--- a/Source/Core/DolphinWX/Src/MemcardManager.h
+++ b/Source/Core/DolphinWX/Src/MemcardManager.h
@@ -29,7 +29,7 @@
#include "IniFile.h"
#include "FileUtil.h"
-#include "MemoryCards/GCMemcard.h"
+#include "HW/GCMemcard.h"
#undef MEMCARD_MANAGER_STYLE
#define MEMCARD_MANAGER_STYLE wxCAPTION | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxCLOSE_BOX | wxRESIZE_BORDER | wxMAXIMIZE_BOX