diff --git a/Source/Core/Core/Src/HW/GCMemcard.cpp b/Source/Core/Core/Src/HW/GCMemcard.cpp index 646c210b29..cd72a6826d 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.cpp +++ b/Source/Core/Core/Src/HW/GCMemcard.cpp @@ -16,7 +16,6 @@ // http://code.google.com/p/dolphin-emu/ #include "GCMemcard.h" #include "ColorUtil.h" - static void ByteSwap(u8 *valueA, u8 *valueB) { u8 tmp = *valueA; @@ -225,7 +224,7 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis) mcdFile.Close(); } -bool GCMemcard::IsAsciiEncoding() +bool GCMemcard::IsAsciiEncoding() const { return hdr.Encoding == 0; } @@ -267,7 +266,7 @@ void GCMemcard::calc_checksumsBE(u16 *buf, u32 length, u16 *csum, u16 *inv_csum) } } -u32 GCMemcard::TestChecksums() +u32 GCMemcard::TestChecksums() const { u16 csum=0, csum_inv=0; @@ -306,7 +305,7 @@ bool GCMemcard::FixChecksums() return true; } -u8 GCMemcard::GetNumFiles() +u8 GCMemcard::GetNumFiles() const { if (!m_valid) return 0; @@ -320,13 +319,13 @@ u8 GCMemcard::GetNumFiles() return j; } -u8 GCMemcard::GetFileIndex(u8 fileNumber) +u8 GCMemcard::GetFileIndex(u8 fileNumber) const { if (m_valid) { u8 j = 0; - for (int i = 0; i < DIRLEN; i++) + for (u8 i = 0; i < DIRLEN; i++) { if (BE32(dir.Dir[i].Gamecode)!= 0xFFFFFFFF) { @@ -338,10 +337,10 @@ u8 GCMemcard::GetFileIndex(u8 fileNumber) } } } - return -1; + return 0xFF; } -u16 GCMemcard::GetFreeBlocks() +u16 GCMemcard::GetFreeBlocks() const { if (!m_valid) return 0; @@ -349,7 +348,7 @@ u16 GCMemcard::GetFreeBlocks() return BE16(bat.FreeBlocks); } -u8 GCMemcard::TitlePresent(DEntry d) +u8 GCMemcard::TitlePresent(DEntry d) const { if (!m_valid) return DIRLEN; @@ -367,102 +366,113 @@ u8 GCMemcard::TitlePresent(DEntry d) return i; } +bool GCMemcard::GCI_FileName(u8 index, std::string &filename) const +{ + if (!m_valid || index > DIRLEN || (BE32(dir.Dir[index].Gamecode) == 0xFFFFFFFF)) + return false; + filename = std::string((char*)dir.Dir[index].Gamecode, 4) + '_' + (char*)dir.Dir[index].Filename + ".gci"; + return true; +} // DEntry functions, all take u8 index < DIRLEN (127) // Functions that have ascii output take a char *buffer -bool GCMemcard::DEntry_GameCode(u8 index, char *buffer) +std::string GCMemcard::DEntry_GameCode(u8 index) const { - if (!m_valid) - return false; - - memcpy(buffer, dir.Dir[index].Gamecode, 4); - buffer[4] = 0; - return true; + if (!m_valid || index > DIRLEN) + return ""; + return std::string((const char*)dir.Dir[index].Gamecode, 4); } -bool GCMemcard::DEntry_Markercode(u8 index, char *buffer) +std::string GCMemcard::DEntry_Makercode(u8 index) const { - if (!m_valid) - return false; - - memcpy(buffer, dir.Dir[index].Markercode, 2); - buffer[2] = 0; - return true; + if (!m_valid || index > DIRLEN) + return ""; + return std::string((const char*)dir.Dir[index].Makercode, 2); } -bool GCMemcard::DEntry_BIFlags(u8 index, char *buffer) -{ - if (!m_valid) - return false; +std::string GCMemcard::DEntry_BIFlags(u8 index) const +{ + if (!m_valid || index > DIRLEN) + return ""; + + std::string flags; int x = dir.Dir[index].BIFlags; for (int i = 0; i < 8; i++) { - buffer[i] = (x & 0x80) ? '1' : '0'; + flags.push_back((x & 0x80) ? '1' : '0'); x = x << 1; } - buffer[8] = 0; - return true; + flags.push_back(0); + return flags; } -bool GCMemcard::DEntry_FileName(u8 index, char *buffer) +std::string GCMemcard::DEntry_FileName(u8 index) const { - if (!m_valid) - return false; - - memcpy (buffer, (const char*)dir.Dir[index].Filename, DENTRY_STRLEN); - buffer[31] = 0; - return true; + if (!m_valid || index > DIRLEN) + return ""; + return std::string((const char*)dir.Dir[index].Filename, DENTRY_STRLEN); } -u32 GCMemcard::DEntry_ModTime(u8 index) +u32 GCMemcard::DEntry_ModTime(u8 index) const { + if (!m_valid || index > DIRLEN) + return 0xFFFFFFFF; return BE32(dir.Dir[index].ModTime); } -u32 GCMemcard::DEntry_ImageOffset(u8 index) +u32 GCMemcard::DEntry_ImageOffset(u8 index) const { + if (!m_valid || index > DIRLEN) + return 0xFFFFFFFF; return BE32(dir.Dir[index].ImageOffset); } -bool GCMemcard::DEntry_IconFmt(u8 index, char *buffer) +std::string GCMemcard::DEntry_IconFmt(u8 index) const { - if (!m_valid) return false; - + if (!m_valid || index > DIRLEN) + return ""; int x = dir.Dir[index].IconFmt[0]; + std::string format; for(int i = 0; i < 16; i++) { if (i == 8) x = dir.Dir[index].IconFmt[1]; - buffer[i] = (x & 0x80) ? '1' : '0'; + format.push_back((x & 0x80) ? '1' : '0'); x = x << 1; } - buffer[16] = 0; - return true; - + format.push_back(0); + return format; } -u16 GCMemcard::DEntry_AnimSpeed(u8 index) +u16 GCMemcard::DEntry_AnimSpeed(u8 index) const { + if (!m_valid || index > DIRLEN) + return 0; return BE16(dir.Dir[index].AnimSpeed); } -bool GCMemcard::DEntry_Permissions(u8 index, char *fn) +std::string GCMemcard::DEntry_Permissions(u8 index) const { - if (!m_valid) return false; - fn[0] = (dir.Dir[index].Permissions & 16) ? 'x' : 'M'; - fn[1] = (dir.Dir[index].Permissions & 8) ? 'x' : 'C'; - fn[2] = (dir.Dir[index].Permissions & 4) ? 'P' : 'x'; - fn[3] = 0; - return true; + if (!m_valid || index > DIRLEN) + return ""; + u8 Permissions = dir.Dir[index].Permissions; + std::string permissionsString; + permissionsString.push_back((Permissions & 16) ? 'x' : 'M'); + permissionsString.push_back((Permissions & 8) ? 'x' : 'C'); + permissionsString.push_back((Permissions & 4) ? 'P' : 'x'); + permissionsString.push_back(0); + return permissionsString; } -u8 GCMemcard::DEntry_CopyCounter(u8 index) +u8 GCMemcard::DEntry_CopyCounter(u8 index) const { + if (!m_valid || index > DIRLEN) + return 0xFF; return dir.Dir[index].CopyCounter; } -u16 GCMemcard::DEntry_FirstBlock(u8 index) +u16 GCMemcard::DEntry_FirstBlock(u8 index) const { - if (!m_valid) + if (!m_valid || index > DIRLEN) return 0xFFFF; u16 block = BE16(dir.Dir[index].FirstBlock); @@ -470,9 +480,9 @@ u16 GCMemcard::DEntry_FirstBlock(u8 index) return block; } -u16 GCMemcard::DEntry_BlockCount(u8 index) +u16 GCMemcard::DEntry_BlockCount(u8 index) const { - if (!m_valid) + if (!m_valid || index > DIRLEN) return 0xFFFF; u16 blocks = BE16(dir.Dir[index].BlockCount); @@ -480,56 +490,51 @@ u16 GCMemcard::DEntry_BlockCount(u8 index) return blocks; } -u32 GCMemcard::DEntry_CommentsAddress(u8 index) +u32 GCMemcard::DEntry_CommentsAddress(u8 index) const { + if (!m_valid || index > DIRLEN) + return 0xFFFF; return BE32(dir.Dir[index].CommentsAddr); } -bool GCMemcard::DEntry_Comment1(u8 index, char* buffer) +std::string GCMemcard::GetSaveComment1(u8 index) const { - if (!m_valid) - return false; + if (!m_valid || index > DIRLEN) + return ""; u32 Comment1 = BE32(dir.Dir[index].CommentsAddr); u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS; if ((DataBlock > maxBlock) || (Comment1 == 0xFFFFFFFF)) { - buffer[0] = 0; - return false; + return ""; } - memcpy(buffer, mc_data + (DataBlock * BLOCK_SIZE) + Comment1, DENTRY_STRLEN); - buffer[31] = 0; - return true; + return std::string((const char *)mc_data + (DataBlock * BLOCK_SIZE) + Comment1, DENTRY_STRLEN); } -bool GCMemcard::DEntry_Comment2(u8 index, char* buffer) +std::string GCMemcard::GetSaveComment2(u8 index) const { - if (!m_valid) - return false; + if (!m_valid || index > DIRLEN) + return ""; u32 Comment1 = BE32(dir.Dir[index].CommentsAddr); u32 Comment2 = Comment1 + DENTRY_STRLEN; u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS; if ((DataBlock > maxBlock) || (Comment1 == 0xFFFFFFFF)) { - buffer[0] = 0; - return false; + return ""; } - memcpy(buffer, mc_data + (DataBlock * BLOCK_SIZE) + Comment2, DENTRY_STRLEN); - buffer[31] = 0; - return true; + return std::string((const char *)mc_data + (DataBlock * BLOCK_SIZE) + Comment2, DENTRY_STRLEN); } -bool GCMemcard::DEntry_Copy(u8 index, GCMemcard::DEntry& info) +bool GCMemcard::GetDEntry(u8 index, DEntry &dest) const { - if (!m_valid) + if (!m_valid || index > DIRLEN) return false; - - info = dir.Dir[index]; + dest = dir.Dir[index]; return true; } -u32 GCMemcard::DEntry_GetSaveData(u8 index, u8* dest, bool old) +u32 GCMemcard::DEntry_GetSaveData(u8 index, u8* dest, bool old) const { if (!m_valid) return NOMEMCARD; @@ -687,13 +692,13 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array while (nextIndex < DIRLEN) { - DEntry * tempDEntry = new DEntry; - DEntry_Copy(nextIndex, *tempDEntry); + DEntry tempDEntry; + GetDEntry(nextIndex, tempDEntry); u8 * tempSaveData = NULL; //Only get file data if it is a valid dir entry - if (BE16(tempDEntry->FirstBlock) != 0xFFFF) + if (BE16(tempDEntry.FirstBlock) != 0xFFFF) { - *(u16*)&bat.FreeBlocks = BE16(BE16(bat.FreeBlocks) - BE16(tempDEntry->BlockCount)); + *(u16*)&bat.FreeBlocks = BE16(BE16(bat.FreeBlocks) - BE16(tempDEntry.BlockCount)); u16 size = DEntry_BlockCount(nextIndex); if (size != 0xFFFF) @@ -707,7 +712,6 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array break; case FAIL: delete[] tempSaveData; - delete tempDEntry; return FAIL; } } @@ -716,10 +720,9 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array //Only call import file if DEntry_GetSaveData returns SUCCESS if (tempSaveData != NULL) { - ImportFile(*tempDEntry, tempSaveData, blocks_left); + ImportFile(tempDEntry, tempSaveData, blocks_left); delete[] tempSaveData; } - delete tempDEntry; nextIndex++; } @@ -737,13 +740,14 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array return SUCCESS; } -u32 GCMemcard::CopyFrom(GCMemcard& source, u8 index) +u32 GCMemcard::CopyFrom(const GCMemcard& source, u8 index) { - if (!m_valid) + if (!m_valid || !source.m_valid) return NOMEMCARD; DEntry tempDEntry; - if (!source.DEntry_Copy(index, tempDEntry)) return NOMEMCARD; + if (!source.GetDEntry(index, tempDEntry)) + return NOMEMCARD; u32 size = source.DEntry_BlockCount(index); if (size == 0xFFFF) return INVALIDFILESIZE; @@ -764,7 +768,7 @@ u32 GCMemcard::CopyFrom(GCMemcard& source, u8 index) } } -u32 GCMemcard::ImportGci(const char *inputFile, std::string outputFile) +u32 GCMemcard::ImportGci(const char *inputFile, const std::string &outputFile) { if (outputFile.empty() && !m_valid) return OPENFAIL; @@ -778,7 +782,7 @@ u32 GCMemcard::ImportGci(const char *inputFile, std::string outputFile) return result; } -u32 GCMemcard::ImportGciInternal(FILE* gcih, const char *inputFile, std::string outputFile) +u32 GCMemcard::ImportGciInternal(FILE* gcih, const char *inputFile, const std::string &outputFile) { File::IOFile gci(gcih); unsigned int offset; @@ -810,8 +814,8 @@ u32 GCMemcard::ImportGciInternal(FILE* gcih, const char *inputFile, std::string } gci.Seek(offset, SEEK_SET); - DEntry *tempDEntry = new DEntry; - gci.ReadBytes(tempDEntry, DENTRY_SIZE); + DEntry tempDEntry; + gci.ReadBytes(&tempDEntry, DENTRY_SIZE); const int fStart = (int)gci.Tell(); gci.Seek(0, SEEK_END); const int length = (int)gci.Tell() - fStart; @@ -819,12 +823,12 @@ u32 GCMemcard::ImportGciInternal(FILE* gcih, const char *inputFile, std::string Gcs_SavConvert(tempDEntry, offset, length); - if (length != BE16(tempDEntry->BlockCount) * BLOCK_SIZE) + if (length != BE16(tempDEntry.BlockCount) * BLOCK_SIZE) return LENGTHFAIL; if (gci.Tell() != offset + DENTRY_SIZE) // Verify correct file position return OPENFAIL; - u32 size = BE16((tempDEntry->BlockCount)) * BLOCK_SIZE; + u32 size = BE16((tempDEntry.BlockCount)) * BLOCK_SIZE; u8 *tempSaveData = new u8[size]; gci.ReadBytes(tempSaveData, size); u32 ret; @@ -835,14 +839,13 @@ u32 GCMemcard::ImportGciInternal(FILE* gcih, const char *inputFile, std::string if (!gci2) { delete[] tempSaveData; - delete tempDEntry; return OPENFAIL; } gci2.Seek(0, SEEK_SET); - if (!gci2.WriteBytes(tempDEntry, DENTRY_SIZE)) + if (!gci2.WriteBytes(&tempDEntry, DENTRY_SIZE)) completeWrite = false; - int fileBlocks = BE16(tempDEntry->BlockCount); + int fileBlocks = BE16(tempDEntry.BlockCount); gci2.Seek(DENTRY_SIZE, SEEK_SET); if (!gci2.WriteBytes(tempSaveData, BLOCK_SIZE * fileBlocks)) @@ -853,14 +856,13 @@ u32 GCMemcard::ImportGciInternal(FILE* gcih, const char *inputFile, std::string ret = WRITEFAIL; } else - ret = ImportFile(*tempDEntry, tempSaveData, 0); + ret = ImportFile(tempDEntry, tempSaveData, 0); delete[] tempSaveData; - delete tempDEntry; return ret; } -u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2) +u32 GCMemcard::ExportGci(u8 index, const char* fileName, const std::string &directory) const { File::IOFile gci; int offset = GCI; @@ -868,15 +870,8 @@ u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2) { if (BE32(dir.Dir[index].Gamecode) == 0xFFFFFFFF) return SUCCESS; - size_t length = fileName2->length() + 42; - char *filename = new char[length]; - char GameCode[5]; - - DEntry_GameCode(index, GameCode); - - sprintf(filename, "%s/%s_%s.gci", fileName2->c_str(), GameCode, dir.Dir[index].Filename); - gci.Open(filename, "wb"); - delete[] filename; + std::string outpuName = directory + DIR_SEP + DEntry_GameCode(index) + '_' + (char*)dir.Dir[index].Filename + ".gci"; + gci.Open(outpuName, "wb"); } else { @@ -917,12 +912,12 @@ u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2) } DEntry tempDEntry; - if (!DEntry_Copy(index, tempDEntry)) + if (!GetDEntry(index, tempDEntry)) { return NOMEMCARD; } - Gcs_SavConvert(&tempDEntry, offset); + Gcs_SavConvert(tempDEntry, offset); gci.WriteBytes(&tempDEntry, DENTRY_SIZE); u32 size = DEntry_BlockCount(index); @@ -955,7 +950,7 @@ u32 GCMemcard::ExportGci(u8 index, const char *fileName, std::string *fileName2) return WRITEFAIL; } -void GCMemcard::Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length) +void GCMemcard::Gcs_SavConvert(DEntry &tempDEntry, int saveType, int length) { switch(saveType) { @@ -965,7 +960,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" - *(u16*)&tempDEntry->BlockCount = BE16(length / BLOCK_SIZE); + *(u16*)&tempDEntry.BlockCount = BE16(length / BLOCK_SIZE); } break; case SAV: @@ -974,24 +969,24 @@ void GCMemcard::Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length) // 0x34 and 0x35, 0x36 and 0x37, 0x38 and 0x39, 0x3A and 0x3B, // 0x3C and 0x3D,0x3E and 0x3F. // It seems that sav files also swap the BIFlags... - ByteSwap(&tempDEntry->Unused1, &tempDEntry->BIFlags); - ArrayByteSwap((tempDEntry->ImageOffset)); - ArrayByteSwap(&(tempDEntry->ImageOffset[2])); - ArrayByteSwap((tempDEntry->IconFmt)); - ArrayByteSwap((tempDEntry->AnimSpeed)); - ByteSwap(&tempDEntry->Permissions, &tempDEntry->CopyCounter); - ArrayByteSwap((tempDEntry->FirstBlock)); - ArrayByteSwap((tempDEntry->BlockCount)); - ArrayByteSwap((tempDEntry->Unused2)); - ArrayByteSwap((tempDEntry->CommentsAddr)); - ArrayByteSwap(&(tempDEntry->CommentsAddr[2])); + ByteSwap(&tempDEntry.Unused1, &tempDEntry.BIFlags); + ArrayByteSwap((tempDEntry.ImageOffset)); + ArrayByteSwap(&(tempDEntry.ImageOffset[2])); + ArrayByteSwap((tempDEntry.IconFmt)); + ArrayByteSwap((tempDEntry.AnimSpeed)); + ByteSwap(&tempDEntry.Permissions, &tempDEntry.CopyCounter); + ArrayByteSwap((tempDEntry.FirstBlock)); + ArrayByteSwap((tempDEntry.BlockCount)); + ArrayByteSwap((tempDEntry.Unused2)); + ArrayByteSwap((tempDEntry.CommentsAddr)); + ArrayByteSwap(&(tempDEntry.CommentsAddr[2])); break; default: break; } } -bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer) +bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer) const { if (!m_valid) return false; @@ -1032,7 +1027,7 @@ bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer) return true; } -u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) +u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const { if (!m_valid) return 0; diff --git a/Source/Core/Core/Src/HW/GCMemcard.h b/Source/Core/Core/Src/HW/GCMemcard.h index 59cecded32..57a42b9d3a 100644 --- a/Source/Core/Core/Src/HW/GCMemcard.h +++ b/Source/Core/Core/Src/HW/GCMemcard.h @@ -19,6 +19,7 @@ #define __GCMEMCARD_h__ #include "Common.h" +#include "CommonPaths.h" #include "Sram.h" #include "StringUtil.h" #include "EXI_DeviceIPL.h" @@ -101,7 +102,7 @@ private: struct DEntry { u8 Gamecode[4]; //0x00 0x04 Gamecode - u8 Markercode[2]; //0x04 0x02 Makercode + u8 Makercode[2]; //0x04 0x02 Makercode u8 Unused1; //0x06 0x01 reserved/unused (always 0xff, has no effect) u8 BIFlags; //0x07 0x01 banner gfx format and icon animation (Image Key) // bit(s) description @@ -168,67 +169,58 @@ private: }; #pragma pack(pop) - u32 ImportGciInternal(FILE* gcih, const char *inputFile, std::string outputFile); + u32 ImportGciInternal(FILE* gcih, const char *inputFile, const 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 IsValid() const { return m_valid; } + bool IsAsciiEncoding() const; bool Save(); bool Format(bool sjis = false, u16 SizeMb = MemCard2043Mb); static bool Format(u8 * card_data, bool sjis = false, u16 SizeMb = MemCard2043Mb); static void calc_checksumsBE(u16 *buf, u32 length, u16 *csum, u16 *inv_csum); - u32 TestChecksums(); + u32 TestChecksums() const; bool FixChecksums(); // get number of file entries in the directory - u8 GetNumFiles(); - u8 GetFileIndex(u8 fileNumber); + u8 GetNumFiles() const; + u8 GetFileIndex(u8 fileNumber) const; // get the free blocks from bat - u16 GetFreeBlocks(); + u16 GetFreeBlocks() const; // If title already on memcard returns index, otherwise returns -1 - u8 TitlePresent(DEntry d); - - // DEntry functions, all take u8 index < DIRLEN (127) - // Functions that have ascii output take a char *buffer + u8 TitlePresent(DEntry d) const; - // buffer needs to be a char[5] or bigger - bool DEntry_GameCode(u8 index, char *buffer); - // buffer needs to be a char[2] or bigger - bool DEntry_Markercode(u8 index, char *buffer); - // buffer needs to be a char[9] or bigger - bool DEntry_BIFlags(u8 index, char *buffer); - // buffer needs to be a char[32] or bigger - bool DEntry_FileName(u8 index, char *buffer); - u32 DEntry_ModTime(u8 index); - u32 DEntry_ImageOffset(u8 index); - // buffer needs to be a char[17] or bigger - bool DEntry_IconFmt(u8 index, char *buffer); - u16 DEntry_AnimSpeed(u8 index); - // buffer needs to be a char[4] or bigger - bool DEntry_Permissions(u8 index, char *buffer); - u8 DEntry_CopyCounter(u8 index); + bool GCI_FileName(u8 index, std::string &filename) const; + // DEntry functions, all take u8 index < DIRLEN (127) + std::string DEntry_GameCode(u8 index) const; + std::string DEntry_Makercode(u8 index) const; + std::string DEntry_BIFlags(u8 index) const; + std::string DEntry_FileName(u8 index) const; + u32 DEntry_ModTime(u8 index) const; + u32 DEntry_ImageOffset(u8 index) const; + std::string DEntry_IconFmt(u8 index) const; + u16 DEntry_AnimSpeed(u8 index) const; + std::string DEntry_Permissions(u8 index) const; + u8 DEntry_CopyCounter(u8 index) const; // get first block for file - u16 DEntry_FirstBlock(u8 index); + u16 DEntry_FirstBlock(u8 index) const; // get file length in blocks - u16 DEntry_BlockCount(u8 index); - u32 DEntry_CommentsAddress(u8 index); - // buffer needs to be a char[32] or bigger - bool DEntry_Comment1(u8 index, char *buffer); - // buffer needs to be a char[32] or bigger - bool DEntry_Comment2(u8 index, char *buffer); + u16 DEntry_BlockCount(u8 index) const; + u32 DEntry_CommentsAddress(u8 index) const; + std::string GetSaveComment1(u8 index) const; + std::string GetSaveComment2(u8 index) const; // Copies a DEntry from u8 index to DEntry& data - bool DEntry_Copy(u8 index, DEntry& data); + bool GetDEntry(u8 index, DEntry &dest) const; // assumes there's enough space in buffer // 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 - u32 DEntry_GetSaveData(u8 index, u8* buffer, bool old); + u32 DEntry_GetSaveData(u8 index, u8* buffer, bool old) const; // adds the file to the directory and copies its contents // if remove > 0 it will pad bat.map with 0's sizeof remove @@ -238,23 +230,23 @@ public: u32 RemoveFile(u8 index); // reads a save from another memcard, and imports the data into this memcard - u32 CopyFrom(GCMemcard& source, u8 index); + u32 CopyFrom(const GCMemcard& source, u8 index); // reads a .gci/.gcs/.sav file and calls ImportFile or saves out a gci file - u32 ImportGci(const char* inputFile, std::string outputFile); + u32 ImportGci(const char* inputFile,const std::string &outputFile); // writes a .gci file to disk containing index - u32 ExportGci(u8 index, const char* fileName, std::string* fileName2); + u32 ExportGci(u8 index, const char* fileName, const std::string &directory) const; // GCI files are untouched, SAV files are byteswapped // GCS files have the block count set, default is 1 (For export as GCS) - void Gcs_SavConvert(DEntry* tempDEntry, int saveType, int length = BLOCK_SIZE); + static void Gcs_SavConvert(DEntry &tempDEntry, int saveType, int length = BLOCK_SIZE); // reads the banner image - bool ReadBannerRGBA8(u8 index, u32* buffer); + bool ReadBannerRGBA8(u8 index, u32* buffer) const; // reads the animation frames - u32 ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays); + u32 ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const; }; #endif diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp index a7b999f7a6..84e6eb8b1d 100644 --- a/Source/Core/DolphinWX/Src/MemcardManager.cpp +++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp @@ -546,15 +546,16 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) index = memoryCard[slot]->GetFileIndex(index); if (index != wxNOT_FOUND) { - char tempC[10 + DENTRY_STRLEN], - tempC2[DENTRY_STRLEN]; - memoryCard[slot]->DEntry_GameCode(index,tempC); - memoryCard[slot]->DEntry_FileName(index,tempC2); - sprintf(tempC, "%s_%s.gci", tempC, tempC2); + std::string gciFilename; + if (!memoryCard[slot]->GCI_FileName(index, gciFilename)) + { + PanicAlert("invalid index"); + return; + } wxString fileName = wxFileSelector( _("Export save as..."), wxString::From8BitData(DefaultIOPath.c_str()), - wxString::From8BitData(tempC), wxT(".gci"), + wxString::From8BitData(gciFilename.c_str()), wxT(".gci"), _("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) + _("MadCatz Gameshark files(*.gcs)") + wxString(wxT("|*.gcs|")) + _("Datel MaxDrive/Pro files(*.sav)") + wxString(wxT("|*.sav")), @@ -562,7 +563,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) if (fileName.length() > 0) { - if (!CopyDeleteSwitch(memoryCard[slot]->ExportGci(index, fileName.mb_str(), NULL), -1)) + if (!CopyDeleteSwitch(memoryCard[slot]->ExportGci(index, fileName.mb_str(), ""), -1)) { File::Delete(std::string(fileName.mb_str())); } @@ -582,7 +583,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) "%s\nand have the same name as a file on your memcard\nContinue?", path1.c_str())) for (int i = 0; i < DIRLEN; i++) { - CopyDeleteSwitch(memoryCard[slot]->ExportGci(i, ".", &path1), -1); + CopyDeleteSwitch(memoryCard[slot]->ExportGci(i, NULL, path1), -1); } break; } @@ -614,8 +615,7 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card) wxComment, wxBlock, wxFirstBlock, - wxLabel, - tString; + wxLabel; m_MemcardList[card]->Hide(); @@ -689,8 +689,6 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card) for (j = page[card] * itemsPerPage; (j < nFiles) && (j < pagesMax); j++) { - char title[DENTRY_STRLEN]; - char comment[DENTRY_STRLEN]; u16 blocks; u16 firstblock; u8 fileIndex = memoryCard[card]->GetFileIndex(j); @@ -700,8 +698,8 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card) m_MemcardList[card]->SetItem(index, COLUMN_BANNER, wxEmptyString); - if (!memoryCard[card]->DEntry_Comment1(fileIndex, title)) title[0]=0; - if (!memoryCard[card]->DEntry_Comment2(fileIndex, comment)) comment[0]=0; + std::string title = memoryCard[card]->GetSaveComment1(fileIndex); + std::string comment = memoryCard[card]->GetSaveComment2(fileIndex); bool ascii = memoryCard[card]->IsAsciiEncoding(); @@ -721,8 +719,8 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card) // it returns CP-932, in order to use iconv we need to use CP932 wxCSConv SJISConv(wxT("CP932")); #endif - wxTitle = wxString(title, ascii ? *wxConvCurrent : SJISConv); - wxComment = wxString(comment, ascii ? *wxConvCurrent : SJISConv); + wxTitle = wxString(title.c_str(), ascii ? *wxConvCurrent : SJISConv); + wxComment = wxString(comment.c_str(), ascii ? *wxConvCurrent : SJISConv); m_MemcardList[card]->SetItem(index, COLUMN_TITLE, wxTitle); m_MemcardList[card]->SetItem(index, COLUMN_COMMENT, wxComment);