Merge branch 'GCMemcardFixes'
This commit is contained in:
commit
f7c17c6351
File diff suppressed because it is too large
Load Diff
|
@ -19,14 +19,15 @@
|
||||||
#define __GCMEMCARD_h__
|
#define __GCMEMCARD_h__
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "CommonPaths.h"
|
||||||
#include "Sram.h"
|
#include "Sram.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
#include "EXI_DeviceIPL.h"
|
#include "EXI_DeviceIPL.h"
|
||||||
|
|
||||||
|
#define BE64(x) (Common::swap64(x))
|
||||||
#define BE32(x) (Common::swap32(x))
|
#define BE32(x) (Common::swap32(x))
|
||||||
#define BE16(x) (Common::swap16(x))
|
#define BE16(x) (Common::swap16(x))
|
||||||
#define ArrayByteSwap(a) (ByteSwap(a, a+sizeof(u8)));
|
#define ArrayByteSwap(a) (ByteSwap(a, a+sizeof(u8)));
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SLOT_A = 0,
|
SLOT_A = 0,
|
||||||
|
@ -54,6 +55,7 @@ enum
|
||||||
DENTRY_STRLEN = 0x20,
|
DENTRY_STRLEN = 0x20,
|
||||||
DENTRY_SIZE = 0x40,
|
DENTRY_SIZE = 0x40,
|
||||||
BLOCK_SIZE = 0x2000,
|
BLOCK_SIZE = 0x2000,
|
||||||
|
BAT_SIZE = 0xFFB,
|
||||||
|
|
||||||
MemCard59Mb = 0x04,
|
MemCard59Mb = 0x04,
|
||||||
MemCard123Mb = 0x08,
|
MemCard123Mb = 0x08,
|
||||||
|
@ -75,25 +77,28 @@ private:
|
||||||
std::string m_fileName;
|
std::string m_fileName;
|
||||||
|
|
||||||
u32 maxBlock;
|
u32 maxBlock;
|
||||||
u32 mc_data_size;
|
|
||||||
u8* mc_data;
|
|
||||||
|
|
||||||
u16 m_sizeMb;
|
u16 m_sizeMb;
|
||||||
|
struct GCMBlock
|
||||||
|
{
|
||||||
|
GCMBlock(){erase();}
|
||||||
|
void erase() {memset(block, 0xFF, BLOCK_SIZE);}
|
||||||
|
u8 block[BLOCK_SIZE];
|
||||||
|
};
|
||||||
|
std::vector<GCMBlock> mc_data_blocks;
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
struct Header { //Offset Size Description
|
struct Header { //Offset Size Description
|
||||||
// Serial in libogc
|
// Serial in libogc
|
||||||
u8 serial[12]; //0x0000 12 ?
|
u8 serial[12]; //0x0000 12 ?
|
||||||
u64 formatTime; //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
|
u32 SramBias; //0x0014 4 sram bias at time of format
|
||||||
u8 SramLang[4]; //0x0018 4 sram language
|
u32 SramLang; //0x0018 4 sram language
|
||||||
u8 Unk2[4]; //0x001c 4 ? almost always 0
|
u8 Unk2[4]; //0x001c 4 ? almost always 0
|
||||||
// end Serial in libogc
|
// end Serial in libogc
|
||||||
u8 deviceID[2]; //0x0020 2 0 if formated in slot A 1 if formated in slot B
|
u8 deviceID[2]; //0x0020 2 0 if formated in slot A 1 if formated in slot B
|
||||||
u8 SizeMb[2]; //0x0022 2 size of memcard in Mbits
|
u8 SizeMb[2]; //0x0022 2 size of memcard in Mbits
|
||||||
u16 Encoding; //0x0024 2 encoding (ASCII or japanese)
|
u16 Encoding; //0x0024 2 encoding (ASCII or japanese)
|
||||||
u8 Unused1[468]; //0x0026 468 unused (0xff)
|
u8 Unused1[468]; //0x0026 468 unused (0xff)
|
||||||
u8 UpdateCounter[2];//0x01fa 2 update Counter (?, probably unused)
|
u16 UpdateCounter; //0x01fa 2 update Counter (?, probably unused)
|
||||||
u16 Checksum; //0x01fc 2 Additive Checksum
|
u16 Checksum; //0x01fc 2 Additive Checksum
|
||||||
u16 Checksum_Inv; //0x01fe 2 Inverse Checksum
|
u16 Checksum_Inv; //0x01fe 2 Inverse Checksum
|
||||||
u8 Unused2[7680]; //0x0200 0x1e00 unused (0xff)
|
u8 Unused2[7680]; //0x0200 0x1e00 unused (0xff)
|
||||||
|
@ -101,7 +106,7 @@ private:
|
||||||
|
|
||||||
struct DEntry {
|
struct DEntry {
|
||||||
u8 Gamecode[4]; //0x00 0x04 Gamecode
|
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 Unused1; //0x06 0x01 reserved/unused (always 0xff, has no effect)
|
||||||
u8 BIFlags; //0x07 0x01 banner gfx format and icon animation (Image Key)
|
u8 BIFlags; //0x07 0x01 banner gfx format and icon animation (Image Key)
|
||||||
// bit(s) description
|
// bit(s) description
|
||||||
|
@ -147,19 +152,25 @@ private:
|
||||||
struct Directory {
|
struct Directory {
|
||||||
DEntry Dir[DIRLEN]; //0x0000 Directory Entries (max 127)
|
DEntry Dir[DIRLEN]; //0x0000 Directory Entries (max 127)
|
||||||
u8 Padding[0x3a];
|
u8 Padding[0x3a];
|
||||||
u8 UpdateCounter[2];//0x1ffa 2 update Counter
|
u16 UpdateCounter; //0x1ffa 2 update Counter
|
||||||
u16 Checksum; //0x1ffc 2 Additive Checksum
|
u16 Checksum; //0x1ffc 2 Additive Checksum
|
||||||
u16 Checksum_Inv; //0x1ffe 2 Inverse Checksum
|
u16 Checksum_Inv; //0x1ffe 2 Inverse Checksum
|
||||||
} dir, dir_backup;
|
} dir, dir_backup;
|
||||||
|
|
||||||
|
Directory *CurrentDir, *PreviousDir;
|
||||||
struct BlockAlloc {
|
struct BlockAlloc {
|
||||||
u16 Checksum; //0x0000 2 Additive Checksum
|
u16 Checksum; //0x0000 2 Additive Checksum
|
||||||
u16 Checksum_Inv; //0x0002 2 Inverse Checksum
|
u16 Checksum_Inv; //0x0002 2 Inverse Checksum
|
||||||
u8 UpdateCounter[2];//0x0004 2 update Counter
|
u16 UpdateCounter; //0x0004 2 update Counter
|
||||||
u8 FreeBlocks[2]; //0x0006 2 free Blocks
|
u16 FreeBlocks; //0x0006 2 free Blocks
|
||||||
u8 LastAllocated[2];//0x0008 2 last allocated Block
|
u16 LastAllocated; //0x0008 2 last allocated Block
|
||||||
u16 Map[0xFFB]; //0x000a 0x1ff8 Map of allocated Blocks
|
u16 Map[BAT_SIZE]; //0x000a 0x1ff8 Map of allocated Blocks
|
||||||
|
u16 GetNextBlock(u16 Block) const;
|
||||||
|
u16 NextFreeBlock(u16 StartingBlock=MC_FST_BLOCKS) const;
|
||||||
|
bool ClearBlocks(u16 StartingBlock, u16 Length);
|
||||||
} bat,bat_backup;
|
} bat,bat_backup;
|
||||||
|
|
||||||
|
BlockAlloc *CurrentBat, *PreviousBat;
|
||||||
struct GCMC_Header
|
struct GCMC_Header
|
||||||
{
|
{
|
||||||
Header *hdr;
|
Header *hdr;
|
||||||
|
@ -168,92 +179,83 @@ private:
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#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);
|
static void FormatInternal(GCMC_Header &GCP);
|
||||||
public:
|
public:
|
||||||
|
|
||||||
GCMemcard(const char* fileName, bool forceCreation=false, bool sjis=false);
|
GCMemcard(const char* fileName, bool forceCreation=false, bool sjis=false);
|
||||||
bool IsValid() { return m_valid; }
|
bool IsValid() const { return m_valid; }
|
||||||
bool IsAsciiEncoding();
|
bool IsAsciiEncoding() const;
|
||||||
bool Save();
|
bool Save();
|
||||||
bool Format(bool sjis = false, u16 SizeMb = MemCard2043Mb);
|
bool Format(bool sjis = false, u16 SizeMb = MemCard2043Mb);
|
||||||
static bool Format(u8 * card_data, 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);
|
static void calc_checksumsBE(u16 *buf, u32 length, u16 *csum, u16 *inv_csum);
|
||||||
u32 TestChecksums();
|
u32 TestChecksums() const;
|
||||||
bool FixChecksums();
|
bool FixChecksums();
|
||||||
|
|
||||||
// get number of file entries in the directory
|
// get number of file entries in the directory
|
||||||
u8 GetNumFiles();
|
u8 GetNumFiles() const;
|
||||||
|
u8 GetFileIndex(u8 fileNumber) const;
|
||||||
|
|
||||||
// get the free blocks from bat
|
// get the free blocks from bat
|
||||||
u16 GetFreeBlocks();
|
u16 GetFreeBlocks() const;
|
||||||
|
|
||||||
// If title already on memcard returns index, otherwise returns -1
|
// If title already on memcard returns index, otherwise returns -1
|
||||||
u8 TitlePresent(DEntry d);
|
u8 TitlePresent(DEntry d) const;
|
||||||
|
|
||||||
|
bool GCI_FileName(u8 index, std::string &filename) const;
|
||||||
// DEntry functions, all take u8 index < DIRLEN (127)
|
// DEntry functions, all take u8 index < DIRLEN (127)
|
||||||
// Functions that have ascii output take a char *buffer
|
std::string DEntry_GameCode(u8 index) const;
|
||||||
|
std::string DEntry_Makercode(u8 index) const;
|
||||||
// buffer needs to be a char[5] or bigger
|
std::string DEntry_BIFlags(u8 index) const;
|
||||||
bool DEntry_GameCode(u8 index, char *buffer);
|
std::string DEntry_FileName(u8 index) const;
|
||||||
// buffer needs to be a char[2] or bigger
|
u32 DEntry_ModTime(u8 index) const;
|
||||||
bool DEntry_Markercode(u8 index, char *buffer);
|
u32 DEntry_ImageOffset(u8 index) const;
|
||||||
// buffer needs to be a char[9] or bigger
|
std::string DEntry_IconFmt(u8 index) const;
|
||||||
bool DEntry_BIFlags(u8 index, char *buffer);
|
u16 DEntry_AnimSpeed(u8 index) const;
|
||||||
// buffer needs to be a char[32] or bigger
|
std::string DEntry_Permissions(u8 index) const;
|
||||||
bool DEntry_FileName(u8 index, char *buffer);
|
u8 DEntry_CopyCounter(u8 index) const;
|
||||||
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);
|
|
||||||
// get first block for file
|
// get first block for file
|
||||||
u16 DEntry_FirstBlock(u8 index);
|
u16 DEntry_FirstBlock(u8 index) const;
|
||||||
// get file length in blocks
|
// get file length in blocks
|
||||||
u16 DEntry_BlockCount(u8 index);
|
u16 DEntry_BlockCount(u8 index) const;
|
||||||
u32 DEntry_CommentsAddress(u8 index);
|
u32 DEntry_CommentsAddress(u8 index) const;
|
||||||
// buffer needs to be a char[32] or bigger
|
std::string GetSaveComment1(u8 index) const;
|
||||||
bool DEntry_Comment1(u8 index, char *buffer);
|
std::string GetSaveComment2(u8 index) const;
|
||||||
// buffer needs to be a char[32] or bigger
|
|
||||||
bool DEntry_Comment2(u8 index, char *buffer);
|
|
||||||
// Copies a DEntry from u8 index to DEntry& data
|
// 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
|
// assumes there's enough space in buffer
|
||||||
// old determines if function uses old or new method of copying data
|
// 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
|
// 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
|
// TODO: find a function that works for all calls or split into 2 functions
|
||||||
u32 DEntry_GetSaveData(u8 index, u8* buffer, bool old);
|
u32 GetSaveData(u8 index, std::vector<GCMBlock> &saveBlocks) const;
|
||||||
|
|
||||||
// adds the file to the directory and copies its contents
|
// adds the file to the directory and copies its contents
|
||||||
// if remove > 0 it will pad bat.map with 0's sizeof remove
|
u32 ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks);
|
||||||
u32 ImportFile(DEntry& direntry, u8* contents, int remove);
|
|
||||||
|
|
||||||
// delete a file from the directory
|
// delete a file from the directory
|
||||||
u32 RemoveFile(u8 index);
|
u32 RemoveFile(u8 index);
|
||||||
|
|
||||||
// reads a save from another memcard, and imports the data into this memcard
|
// 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
|
// 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
|
// 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
|
// GCI files are untouched, SAV files are byteswapped
|
||||||
// GCS files have the block count set, default is 1 (For export as GCS)
|
// 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
|
// reads the banner image
|
||||||
bool ReadBannerRGBA8(u8 index, u32* buffer);
|
bool ReadBannerRGBA8(u8 index, u32* buffer) const;
|
||||||
|
|
||||||
// reads the animation frames
|
// reads the animation frames
|
||||||
u32 ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays);
|
u32 ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ CMemcardManager::CMemcardManager(wxWindow* parent, wxWindowID id, const wxString
|
||||||
memoryCard[SLOT_A]=NULL;
|
memoryCard[SLOT_A]=NULL;
|
||||||
memoryCard[SLOT_B]=NULL;
|
memoryCard[SLOT_B]=NULL;
|
||||||
|
|
||||||
|
mcmSettings.twoCardsLoaded = false;
|
||||||
if (!LoadSettings())
|
if (!LoadSettings())
|
||||||
{
|
{
|
||||||
itemsPerPage = 16;
|
itemsPerPage = 16;
|
||||||
|
@ -283,7 +284,7 @@ void CMemcardManager::ChangePath(int slot)
|
||||||
m_PrevPage[slot]->Disable();
|
m_PrevPage[slot]->Disable();
|
||||||
m_MemcardList[slot]->prevPage = false;
|
m_MemcardList[slot]->prevPage = false;
|
||||||
}
|
}
|
||||||
if (!strcasecmp(m_MemcardPath[slot2]->GetPath().mb_str(), m_MemcardPath[slot]->GetPath().mb_str()))
|
if (!m_MemcardPath[SLOT_A]->GetPath().CmpNoCase(m_MemcardPath[SLOT_B]->GetPath()))
|
||||||
{
|
{
|
||||||
if(m_MemcardPath[slot]->GetPath().length())
|
if(m_MemcardPath[slot]->GetPath().length())
|
||||||
PanicAlertT("Memcard already opened");
|
PanicAlertT("Memcard already opened");
|
||||||
|
@ -292,7 +293,10 @@ void CMemcardManager::ChangePath(int slot)
|
||||||
{
|
{
|
||||||
if (m_MemcardPath[slot]->GetPath().length() && ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot))
|
if (m_MemcardPath[slot]->GetPath().length() && ReloadMemcard(m_MemcardPath[slot]->GetPath().mb_str(), slot))
|
||||||
{
|
{
|
||||||
mcmSettings.twoCardsLoaded = true;
|
if (memoryCard[slot2])
|
||||||
|
{
|
||||||
|
mcmSettings.twoCardsLoaded = true;
|
||||||
|
}
|
||||||
m_SaveImport[slot]->Enable();
|
m_SaveImport[slot]->Enable();
|
||||||
m_SaveExport[slot]->Enable();
|
m_SaveExport[slot]->Enable();
|
||||||
m_Delete[slot]->Enable();
|
m_Delete[slot]->Enable();
|
||||||
|
@ -318,16 +322,9 @@ void CMemcardManager::ChangePath(int slot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m_Delete[SLOT_A]->IsEnabled() && m_Delete[SLOT_B]->IsEnabled())
|
|
||||||
{
|
m_CopyFrom[SLOT_A]->Enable(mcmSettings.twoCardsLoaded);
|
||||||
m_CopyFrom[SLOT_A]->Enable();
|
m_CopyFrom[SLOT_B]->Enable(mcmSettings.twoCardsLoaded);
|
||||||
m_CopyFrom[SLOT_B]->Enable();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_CopyFrom[SLOT_A]->Disable();
|
|
||||||
m_CopyFrom[SLOT_B]->Disable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMemcardManager::OnPageChange(wxCommandEvent& event)
|
void CMemcardManager::OnPageChange(wxCommandEvent& event)
|
||||||
|
@ -496,6 +493,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
|
||||||
slot2 = SLOT_B;
|
slot2 = SLOT_B;
|
||||||
case ID_COPYFROM_A:
|
case ID_COPYFROM_A:
|
||||||
index = slot2 ? index_B : index_A;
|
index = slot2 ? index_B : index_A;
|
||||||
|
index = memoryCard[slot2]->GetFileIndex(index);
|
||||||
if ((index != wxNOT_FOUND))
|
if ((index != wxNOT_FOUND))
|
||||||
{
|
{
|
||||||
CopyDeleteSwitch(memoryCard[slot]->CopyFrom(*memoryCard[slot2], index), slot);
|
CopyDeleteSwitch(memoryCard[slot]->CopyFrom(*memoryCard[slot2], index), slot);
|
||||||
|
@ -545,17 +543,19 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
|
||||||
slot=SLOT_A;
|
slot=SLOT_A;
|
||||||
index = index_A;
|
index = index_A;
|
||||||
case ID_SAVEEXPORT_B:
|
case ID_SAVEEXPORT_B:
|
||||||
|
index = memoryCard[slot]->GetFileIndex(index);
|
||||||
if (index != wxNOT_FOUND)
|
if (index != wxNOT_FOUND)
|
||||||
{
|
{
|
||||||
char tempC[10 + DENTRY_STRLEN],
|
std::string gciFilename;
|
||||||
tempC2[DENTRY_STRLEN];
|
if (!memoryCard[slot]->GCI_FileName(index, gciFilename))
|
||||||
memoryCard[slot]->DEntry_GameCode(index,tempC);
|
{
|
||||||
memoryCard[slot]->DEntry_FileName(index,tempC2);
|
PanicAlert("invalid index");
|
||||||
sprintf(tempC, "%s_%s.gci", tempC, tempC2);
|
return;
|
||||||
|
}
|
||||||
wxString fileName = wxFileSelector(
|
wxString fileName = wxFileSelector(
|
||||||
_("Export save as..."),
|
_("Export save as..."),
|
||||||
wxString::From8BitData(DefaultIOPath.c_str()),
|
wxString::From8BitData(DefaultIOPath.c_str()),
|
||||||
wxString::From8BitData(tempC), wxT(".gci"),
|
wxString::From8BitData(gciFilename.c_str()), wxT(".gci"),
|
||||||
_("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) +
|
_("Native GCI files(*.gci)") + wxString(wxT("|*.gci|")) +
|
||||||
_("MadCatz Gameshark files(*.gcs)") + wxString(wxT("|*.gcs|")) +
|
_("MadCatz Gameshark files(*.gcs)") + wxString(wxT("|*.gcs|")) +
|
||||||
_("Datel MaxDrive/Pro files(*.sav)") + wxString(wxT("|*.sav")),
|
_("Datel MaxDrive/Pro files(*.sav)") + wxString(wxT("|*.sav")),
|
||||||
|
@ -563,7 +563,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
|
||||||
|
|
||||||
if (fileName.length() > 0)
|
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()));
|
File::Delete(std::string(fileName.mb_str()));
|
||||||
}
|
}
|
||||||
|
@ -583,7 +583,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
|
||||||
"%s\nand have the same name as a file on your memcard\nContinue?", path1.c_str()))
|
"%s\nand have the same name as a file on your memcard\nContinue?", path1.c_str()))
|
||||||
for (int i = 0; i < DIRLEN; i++)
|
for (int i = 0; i < DIRLEN; i++)
|
||||||
{
|
{
|
||||||
CopyDeleteSwitch(memoryCard[slot]->ExportGci(i, ".", &path1), -1);
|
CopyDeleteSwitch(memoryCard[slot]->ExportGci(i, NULL, path1), -1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -591,6 +591,7 @@ void CMemcardManager::CopyDeleteClick(wxCommandEvent& event)
|
||||||
slot = SLOT_A;
|
slot = SLOT_A;
|
||||||
index = index_A;
|
index = index_A;
|
||||||
case ID_DELETE_B:
|
case ID_DELETE_B:
|
||||||
|
index = memoryCard[slot]->GetFileIndex(index);
|
||||||
if (index != wxNOT_FOUND)
|
if (index != wxNOT_FOUND)
|
||||||
{
|
{
|
||||||
CopyDeleteSwitch(memoryCard[slot]->RemoveFile(index), slot);
|
CopyDeleteSwitch(memoryCard[slot]->RemoveFile(index), slot);
|
||||||
|
@ -614,8 +615,7 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card)
|
||||||
wxComment,
|
wxComment,
|
||||||
wxBlock,
|
wxBlock,
|
||||||
wxFirstBlock,
|
wxFirstBlock,
|
||||||
wxLabel,
|
wxLabel;
|
||||||
tString;
|
|
||||||
|
|
||||||
|
|
||||||
m_MemcardList[card]->Hide();
|
m_MemcardList[card]->Hide();
|
||||||
|
@ -631,18 +631,19 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card)
|
||||||
wxImageList *list = m_MemcardList[card]->GetImageList(wxIMAGE_LIST_SMALL);
|
wxImageList *list = m_MemcardList[card]->GetImageList(wxIMAGE_LIST_SMALL);
|
||||||
list->RemoveAll();
|
list->RemoveAll();
|
||||||
|
|
||||||
int nFiles = memoryCard[card]->GetNumFiles();
|
u8 nFiles = memoryCard[card]->GetNumFiles();
|
||||||
int *images = new int[nFiles*2];
|
int *images = new int[nFiles*2];
|
||||||
|
|
||||||
for (int i = 0;i < nFiles;i++)
|
for (u8 i = 0;i < nFiles;i++)
|
||||||
{
|
{
|
||||||
static u32 pxdata[96*32];
|
static u32 pxdata[96*32];
|
||||||
static u8 animDelay[8];
|
static u8 animDelay[8];
|
||||||
static u32 animData[32*32*8];
|
static u32 animData[32*32*8];
|
||||||
|
|
||||||
int numFrames = memoryCard[card]->ReadAnimRGBA8(i,animData,animDelay);
|
u8 fileIndex = memoryCard[card]->GetFileIndex(i);
|
||||||
|
int numFrames = memoryCard[card]->ReadAnimRGBA8(fileIndex, animData, animDelay);
|
||||||
|
|
||||||
if (!memoryCard[card]->ReadBannerRGBA8(i,pxdata))
|
if (!memoryCard[card]->ReadBannerRGBA8(fileIndex, pxdata))
|
||||||
{
|
{
|
||||||
memset(pxdata,0,96*32*4);
|
memset(pxdata,0,96*32*4);
|
||||||
|
|
||||||
|
@ -688,17 +689,17 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card)
|
||||||
|
|
||||||
for (j = page[card] * itemsPerPage; (j < nFiles) && (j < pagesMax); j++)
|
for (j = page[card] * itemsPerPage; (j < nFiles) && (j < pagesMax); j++)
|
||||||
{
|
{
|
||||||
char title[DENTRY_STRLEN];
|
|
||||||
char comment[DENTRY_STRLEN];
|
|
||||||
u16 blocks;
|
u16 blocks;
|
||||||
u16 firstblock;
|
u16 firstblock;
|
||||||
|
u8 fileIndex = memoryCard[card]->GetFileIndex(j);
|
||||||
|
|
||||||
|
|
||||||
int index = m_MemcardList[card]->InsertItem(j, wxEmptyString);
|
int index = m_MemcardList[card]->InsertItem(j, wxEmptyString);
|
||||||
|
|
||||||
m_MemcardList[card]->SetItem(index, COLUMN_BANNER, wxEmptyString);
|
m_MemcardList[card]->SetItem(index, COLUMN_BANNER, wxEmptyString);
|
||||||
|
|
||||||
if (!memoryCard[card]->DEntry_Comment1(j, title)) title[0]=0;
|
std::string title = memoryCard[card]->GetSaveComment1(fileIndex);
|
||||||
if (!memoryCard[card]->DEntry_Comment2(j, comment)) comment[0]=0;
|
std::string comment = memoryCard[card]->GetSaveComment2(fileIndex);
|
||||||
|
|
||||||
bool ascii = memoryCard[card]->IsAsciiEncoding();
|
bool ascii = memoryCard[card]->IsAsciiEncoding();
|
||||||
|
|
||||||
|
@ -718,20 +719,20 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card)
|
||||||
// it returns CP-932, in order to use iconv we need to use CP932
|
// it returns CP-932, in order to use iconv we need to use CP932
|
||||||
wxCSConv SJISConv(wxT("CP932"));
|
wxCSConv SJISConv(wxT("CP932"));
|
||||||
#endif
|
#endif
|
||||||
wxTitle = wxString(title, ascii ? *wxConvCurrent : SJISConv);
|
wxTitle = wxString(title.c_str(), ascii ? *wxConvCurrent : SJISConv);
|
||||||
wxComment = wxString(comment, 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_TITLE, wxTitle);
|
||||||
m_MemcardList[card]->SetItem(index, COLUMN_COMMENT, wxComment);
|
m_MemcardList[card]->SetItem(index, COLUMN_COMMENT, wxComment);
|
||||||
|
|
||||||
blocks = memoryCard[card]->DEntry_BlockCount(j);
|
blocks = memoryCard[card]->DEntry_BlockCount(fileIndex);
|
||||||
if (blocks == 0xFFFF) blocks = 0;
|
if (blocks == 0xFFFF) blocks = 0;
|
||||||
wxBlock.Printf(wxT("%10d"), blocks);
|
wxBlock.Printf(wxT("%10d"), blocks);
|
||||||
m_MemcardList[card]->SetItem(index,COLUMN_BLOCKS, wxBlock);
|
m_MemcardList[card]->SetItem(index,COLUMN_BLOCKS, wxBlock);
|
||||||
firstblock = memoryCard[card]->DEntry_FirstBlock(j);
|
firstblock = memoryCard[card]->DEntry_FirstBlock(fileIndex);
|
||||||
if (firstblock == 0xFFFF) firstblock = 3; // to make firstblock -1
|
//if (firstblock == 0xFFFF) firstblock = 3; // to make firstblock -1
|
||||||
wxFirstBlock.Printf(wxT("%15d"), firstblock-4);
|
wxFirstBlock.Printf(wxT("%15d"), firstblock);
|
||||||
m_MemcardList[card]->SetItem(index,COLUMN_FIRSTBLOCK, wxFirstBlock);
|
m_MemcardList[card]->SetItem(index, COLUMN_FIRSTBLOCK, wxFirstBlock);
|
||||||
m_MemcardList[card]->SetItem(index, COLUMN_ICON, wxEmptyString);
|
m_MemcardList[card]->SetItem(index, COLUMN_ICON, wxEmptyString);
|
||||||
|
|
||||||
if (images[j] >= 0)
|
if (images[j] >= 0)
|
||||||
|
|
Loading…
Reference in New Issue