Update directorys and BlockAllocs correctly, use the most uptodate directory/bat instead of always the first

Signed-off-by: LPFaint99 <lpfaint99@gmail.com>
This commit is contained in:
LPFaint99 2012-02-06 17:27:49 -08:00
parent 1fe67e19ab
commit 3d20c57458
3 changed files with 164 additions and 187 deletions

View File

@ -227,6 +227,28 @@ GCMemcard::GCMemcard(const char *filename, bool forceCreation, bool sjis)
}
mcdFile.Close();
if (BE16(dir.UpdateCounter) > (BE16(dir_backup.UpdateCounter)))
{
CurrentDir = &dir;
PreviousDir = &dir_backup;
}
else
{
CurrentDir = &dir_backup;
PreviousDir = &dir;
}
if (BE16(bat.UpdateCounter) > BE16(bat_backup.UpdateCounter))
{
PanicAlert("jere, %x, %x",BE16(bat.UpdateCounter) , BE16(bat_backup.UpdateCounter));
CurrentBat = &bat;
PreviousBat = &bat_backup;
}
else
{
CurrentBat = &bat_backup;
PreviousBat = &bat;
}
}
bool GCMemcard::IsAsciiEncoding() const
@ -321,7 +343,7 @@ u8 GCMemcard::GetNumFiles() const
u8 j = 0;
for (int i = 0; i < DIRLEN; i++)
{
if (BE32(dir.Dir[i].Gamecode)!= 0xFFFFFFFF)
if (BE32(CurrentDir->Dir[i].Gamecode)!= 0xFFFFFFFF)
j++;
}
return j;
@ -335,7 +357,7 @@ u8 GCMemcard::GetFileIndex(u8 fileNumber) const
u8 j = 0;
for (u8 i = 0; i < DIRLEN; i++)
{
if (BE32(dir.Dir[i].Gamecode)!= 0xFFFFFFFF)
if (BE32(CurrentDir->Dir[i].Gamecode)!= 0xFFFFFFFF)
{
if (j == fileNumber)
{
@ -353,7 +375,7 @@ u16 GCMemcard::GetFreeBlocks() const
if (!m_valid)
return 0;
return BE16(bat.FreeBlocks);
return BE16(CurrentBat->FreeBlocks);
}
u8 GCMemcard::TitlePresent(DEntry d) const
@ -364,8 +386,8 @@ u8 GCMemcard::TitlePresent(DEntry d) const
u8 i = 0;
while(i < DIRLEN)
{
if ((BE32(dir.Dir[i].Gamecode) == BE32(d.Gamecode)) &&
(!memcmp(dir.Dir[i].Filename, d.Filename, 32)))
if ((BE32(CurrentDir->Dir[i].Gamecode) == BE32(d.Gamecode)) &&
(!memcmp(CurrentDir->Dir[i].Filename, d.Filename, 32)))
{
break;
}
@ -376,9 +398,9 @@ u8 GCMemcard::TitlePresent(DEntry d) const
bool GCMemcard::GCI_FileName(u8 index, std::string &filename) const
{
if (!m_valid || index > DIRLEN || (BE32(dir.Dir[index].Gamecode) == 0xFFFFFFFF))
if (!m_valid || index > DIRLEN || (BE32(CurrentDir->Dir[index].Gamecode) == 0xFFFFFFFF))
return false;
filename = std::string((char*)dir.Dir[index].Gamecode, 4) + '_' + (char*)dir.Dir[index].Filename + ".gci";
filename = std::string((char*)CurrentDir->Dir[index].Gamecode, 4) + '_' + (char*)CurrentDir->Dir[index].Filename + ".gci";
return true;
}
@ -389,14 +411,14 @@ std::string GCMemcard::DEntry_GameCode(u8 index) const
{
if (!m_valid || index > DIRLEN)
return "";
return std::string((const char*)dir.Dir[index].Gamecode, 4);
return std::string((const char*)CurrentDir->Dir[index].Gamecode, 4);
}
std::string GCMemcard::DEntry_Makercode(u8 index) const
{
if (!m_valid || index > DIRLEN)
return "";
return std::string((const char*)dir.Dir[index].Makercode, 2);
return std::string((const char*)CurrentDir->Dir[index].Makercode, 2);
}
std::string GCMemcard::DEntry_BIFlags(u8 index) const
@ -405,7 +427,7 @@ std::string GCMemcard::DEntry_BIFlags(u8 index) const
return "";
std::string flags;
int x = dir.Dir[index].BIFlags;
int x = CurrentDir->Dir[index].BIFlags;
for (int i = 0; i < 8; i++)
{
flags.push_back((x & 0x80) ? '1' : '0');
@ -419,32 +441,32 @@ std::string GCMemcard::DEntry_FileName(u8 index) const
{
if (!m_valid || index > DIRLEN)
return "";
return std::string((const char*)dir.Dir[index].Filename, DENTRY_STRLEN);
return std::string((const char*)CurrentDir->Dir[index].Filename, DENTRY_STRLEN);
}
u32 GCMemcard::DEntry_ModTime(u8 index) const
{
if (!m_valid || index > DIRLEN)
return 0xFFFFFFFF;
return BE32(dir.Dir[index].ModTime);
return BE32(CurrentDir->Dir[index].ModTime);
}
u32 GCMemcard::DEntry_ImageOffset(u8 index) const
{
if (!m_valid || index > DIRLEN)
return 0xFFFFFFFF;
return BE32(dir.Dir[index].ImageOffset);
return BE32(CurrentDir->Dir[index].ImageOffset);
}
std::string GCMemcard::DEntry_IconFmt(u8 index) const
{
if (!m_valid || index > DIRLEN)
return "";
int x = dir.Dir[index].IconFmt[0];
int x = CurrentDir->Dir[index].IconFmt[0];
std::string format;
for(int i = 0; i < 16; i++)
{
if (i == 8) x = dir.Dir[index].IconFmt[1];
if (i == 8) x = CurrentDir->Dir[index].IconFmt[1];
format.push_back((x & 0x80) ? '1' : '0');
x = x << 1;
}
@ -456,14 +478,14 @@ u16 GCMemcard::DEntry_AnimSpeed(u8 index) const
{
if (!m_valid || index > DIRLEN)
return 0xFF;
return BE16(dir.Dir[index].AnimSpeed);
return BE16(CurrentDir->Dir[index].AnimSpeed);
}
std::string GCMemcard::DEntry_Permissions(u8 index) const
{
if (!m_valid || index > DIRLEN)
return "";
u8 Permissions = dir.Dir[index].Permissions;
u8 Permissions = CurrentDir->Dir[index].Permissions;
std::string permissionsString;
permissionsString.push_back((Permissions & 16) ? 'x' : 'M');
permissionsString.push_back((Permissions & 8) ? 'x' : 'C');
@ -476,7 +498,7 @@ u8 GCMemcard::DEntry_CopyCounter(u8 index) const
{
if (!m_valid || index > DIRLEN)
return 0xFF;
return dir.Dir[index].CopyCounter;
return CurrentDir->Dir[index].CopyCounter;
}
u16 GCMemcard::DEntry_FirstBlock(u8 index) const
@ -484,7 +506,7 @@ u16 GCMemcard::DEntry_FirstBlock(u8 index) const
if (!m_valid || index > DIRLEN)
return 0xFFFF;
u16 block = BE16(dir.Dir[index].FirstBlock);
u16 block = BE16(CurrentDir->Dir[index].FirstBlock);
if (block > (u16) maxBlock) return 0xFFFF;
return block;
}
@ -494,7 +516,7 @@ u16 GCMemcard::DEntry_BlockCount(u8 index) const
if (!m_valid || index > DIRLEN)
return 0xFFFF;
u16 blocks = BE16(dir.Dir[index].BlockCount);
u16 blocks = BE16(CurrentDir->Dir[index].BlockCount);
if (blocks > (u16) maxBlock) return 0xFFFF;
return blocks;
}
@ -503,7 +525,7 @@ u32 GCMemcard::DEntry_CommentsAddress(u8 index) const
{
if (!m_valid || index > DIRLEN)
return 0xFFFF;
return BE32(dir.Dir[index].CommentsAddr);
return BE32(CurrentDir->Dir[index].CommentsAddr);
}
std::string GCMemcard::GetSaveComment1(u8 index) const
@ -511,8 +533,8 @@ std::string GCMemcard::GetSaveComment1(u8 index) const
if (!m_valid || index > DIRLEN)
return "";
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS;
u32 Comment1 = BE32(CurrentDir->Dir[index].CommentsAddr);
u32 DataBlock = BE16(CurrentDir->Dir[index].FirstBlock) - MC_FST_BLOCKS;
if ((DataBlock > maxBlock) || (Comment1 == 0xFFFFFFFF))
{
return "";
@ -525,9 +547,9 @@ std::string GCMemcard::GetSaveComment2(u8 index) const
if (!m_valid || index > DIRLEN)
return "";
u32 Comment1 = BE32(dir.Dir[index].CommentsAddr);
u32 Comment1 = BE32(CurrentDir->Dir[index].CommentsAddr);
u32 Comment2 = Comment1 + DENTRY_STRLEN;
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS;
u32 DataBlock = BE16(CurrentDir->Dir[index].FirstBlock) - MC_FST_BLOCKS;
if ((DataBlock > maxBlock) || (Comment1 == 0xFFFFFFFF))
{
return "";
@ -539,44 +561,47 @@ bool GCMemcard::GetDEntry(u8 index, DEntry &dest) const
{
if (!m_valid || index > DIRLEN)
return false;
dest = dir.Dir[index];
dest = CurrentDir->Dir[index];
return true;
}
u16 GCMemcard::GetNextBlock(u16 Block) const
u16 GCMemcard::BlockAlloc::GetNextBlock(u16 Block) const
{
if ((Block < MC_FST_BLOCKS) || (Block > maxBlock))
if ((Block < MC_FST_BLOCKS) || (Block > 4091))
return 0;
return Common::swap16(bat.Map[Block-MC_FST_BLOCKS]);
return Common::swap16(Map[Block-MC_FST_BLOCKS]);
}
u16 GCMemcard::NextFreeBlock(u16 StartingBlock) const
u16 GCMemcard::BlockAlloc::NextFreeBlock(u16 StartingBlock) const
{
for (u16 i = StartingBlock; i < BAT_SIZE; ++i)
if (bat.Map[i-MC_FST_BLOCKS] == 0)
if (Map[i-MC_FST_BLOCKS] == 0)
return i;
}
bool GCMemcard::ClearBlocks(u16 FirstBlock, u16 BlockCount)
bool GCMemcard::BlockAlloc::ClearBlocks(u16 FirstBlock, u16 BlockCount)
{
std::vector<u16> blocks;
while (FirstBlock != 0xFF && FirstBlock != 0)
while (FirstBlock != 0xFFFF && FirstBlock != 0)
{
blocks.push_back(FirstBlock);
FirstBlock = GetNextBlock(FirstBlock);
}
if (FirstBlock > 0)
{
size_t length = blocks.size();
if (length != BlockCount)
{
return false;
for (int i = 0; i < length; ++i)
bat.Map[blocks.at(i)-MC_FST_BLOCKS] = 0;
*(u16*)&bat.FreeBlocks = BE16(BE16(bat.FreeBlocks) - BlockCount);
}
for (int i = 0; i < length; ++i)
Map[blocks.at(i)-MC_FST_BLOCKS] = 0;
*(u16*)&FreeBlocks = BE16(BE16(FreeBlocks) + BlockCount);
return true;
}
return false;
}
u32 GCMemcard::GetSaveData(u8 index, std::vector<GCMBlock> & Blocks) const
{
if (!m_valid)
@ -597,13 +622,13 @@ u32 GCMemcard::GetSaveData(u8 index, std::vector<GCMBlock> & Blocks) const
if ((!nextBlock) || (nextBlock == 0xFFFF))
return FAIL;
Blocks.push_back(mc_data_blocks[nextBlock-MC_FST_BLOCKS]);
nextBlock = GetNextBlock(nextBlock);
nextBlock = CurrentBat->GetNextBlock(nextBlock);
}
return SUCCESS;
}
// End DEntry functions
u32 GCMemcard::ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks, int remove)
u32 GCMemcard::ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks)
{
if (!m_valid)
return NOMEMCARD;
@ -612,11 +637,11 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks, i
{
return OUTOFDIRENTRIES;
}
if (BE16(bat.FreeBlocks) < BE16(direntry.BlockCount))
if (BE16(CurrentBat->FreeBlocks) < BE16(direntry.BlockCount))
{
return OUTOFBLOCKS;
}
if (!remove && (TitlePresent(direntry) != DIRLEN))
if (TitlePresent(direntry) != DIRLEN)
{
return TITLEPRESENT;
}
@ -625,44 +650,40 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks, i
//int totalspace = (((u32)BE16(hdr.SizeMb) * MBIT_TO_BLOCKS) - MC_FST_BLOCKS);
//int firstFree1 = BE16(bat.LastAllocated) + 1;
u16 firstBlock = CurrentBat->NextFreeBlock();
Directory UpdatedDir = *CurrentDir;
/* for (int i = 0; i < DIRLEN; i++)
{
if (BE32(dir.Dir[i].Gamecode) == 0xFFFFFFFF)
{
break;
}
else
{
firstFree2 = max<int>(firstFree2,
(int)(BE16(dir.Dir[i].FirstBlock) + BE16(dir.Dir[i].BlockCount)));
}
}
firstFree1 = max<int>(firstFree1, firstFree2);
*/
u16 firstBlock = NextFreeBlock();
// find first free dir entry
int index = -1;
for (int i=0; i < DIRLEN; i++)
{
if (BE32(dir.Dir[i].Gamecode) == 0xFFFFFFFF)
if (BE32(UpdatedDir.Dir[i].Gamecode) == 0xFFFFFFFF)
{
index = i;
dir.Dir[i] = direntry;
*(u16*)&dir.Dir[i].FirstBlock = BE16(firstBlock);
if (!remove)
{
dir.Dir[i].CopyCounter = dir.Dir[i].CopyCounter+1;
}
dir_backup = dir;
UpdatedDir.Dir[i] = direntry;
*(u16*)&UpdatedDir.Dir[i].FirstBlock = BE16(firstBlock);
UpdatedDir.Dir[i].CopyCounter = UpdatedDir.Dir[i].CopyCounter+1;
break;
}
}
*(u16*)&UpdatedDir.UpdateCounter = BE16(BE16(UpdatedDir.UpdateCounter) + 1);
*PreviousDir = UpdatedDir;
if (PreviousDir == &dir )
{
CurrentDir = &dir;
PreviousDir = &dir_backup;
}
else
{
CurrentDir = &dir_backup;
PreviousDir = &dir;
}
int fileBlocks = BE16(direntry.BlockCount);
BlockAlloc UpdatedBat = *CurrentBat;
u16 nextBlock;
// keep assuming no freespace fragmentation, and copy over all the data
for (int i = 0; i < fileBlocks; ++i)
@ -671,42 +692,24 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks, i
if (i == fileBlocks-1)
nextBlock = 0xFFFF;
else
nextBlock = NextFreeBlock(firstBlock+1);
bat.Map[firstBlock - MC_FST_BLOCKS] = BE16(nextBlock);
nextBlock = UpdatedBat.NextFreeBlock(firstBlock+1);
UpdatedBat.Map[firstBlock - MC_FST_BLOCKS] = BE16(nextBlock);
firstBlock = nextBlock;
}
bat_backup = bat;
/* u16 last = BE16(bat_backup.LastAllocated);
u16 i = (last - 4);
int j = 2;
while(j < BE16(direntry.BlockCount) + 1)
*(u16*)&UpdatedBat.FreeBlocks = BE16(BE16(UpdatedBat.FreeBlocks) - fileBlocks);
*(u16*)&UpdatedBat.UpdateCounter = BE16(BE16(UpdatedBat.UpdateCounter) + 1);
*PreviousBat = UpdatedBat;
if (PreviousBat == &bat )
{
bat_backup.Map[i] = BE16(last + (u16)j);
i++;
j++;
CurrentBat = &bat;
PreviousBat = &bat_backup;
}
bat_backup.Map[i++] = 0xFFFF;
//Set bat.map to 0 for each block that was removed
for (int k = 0; k < remove; k++)
else
{
bat_backup.Map[i++] = 0x0000;
CurrentBat = &bat_backup;
PreviousBat = &bat;
}
*/
//update last allocated block
/* *(u16*)&bat_backup.LastAllocated = BE16(BE16(bat_backup.LastAllocated) + j - 1);
*/
//update freespace counter
*(u16*)&bat_backup.FreeBlocks = BE16(BE16(bat_backup.FreeBlocks) - fileBlocks);
if (!remove)
{ // ... and dir update counter
*(u16*)&dir_backup.UpdateCounter = BE16(BE16(dir_backup.UpdateCounter) + 1);
// ... and bat update counter
*(u16*)&bat_backup.UpdateCounter = BE16(BE16(bat_backup.UpdateCounter) + 1);
}
bat = bat_backup;
return SUCCESS;
}
@ -717,86 +720,58 @@ u32 GCMemcard::RemoveFile(u8 index) //index in the directory array
if (index >= DIRLEN)
return DELETE_FAIL;
dir_backup = dir;
bat_backup = bat;
u16 startingblock = BE16(dir.Dir[index].FirstBlock);
u16 numberofblocks = BE16(dir.Dir[index].BlockCount);
if (!ClearBlocks(startingblock, numberofblocks))
BlockAlloc UpdatedBat = *CurrentBat;
if (!UpdatedBat.ClearBlocks(startingblock, numberofblocks))
return DELETE_FAIL;
*(u16*)&UpdatedBat.UpdateCounter = BE16(BE16(UpdatedBat.UpdateCounter) + 1);
*PreviousBat = UpdatedBat;
if (PreviousBat == &bat )
{
CurrentBat = &bat;
PreviousBat = &bat_backup;
}
else
{
CurrentBat = &bat_backup;
PreviousBat = &bat;
}
Directory UpdatedDir = *CurrentDir;
*(u32*)&UpdatedDir.Dir[index].Gamecode = 0;
*(u16*)&UpdatedDir.Dir[index].Makercode = 0;
memset(UpdatedDir.Dir[index].Filename, 0, 0x20);
strcpy((char*)UpdatedDir.Dir[index].Filename, "Broken File000");
*(u16*)&UpdatedDir.UpdateCounter = BE16(BE16(UpdatedDir.UpdateCounter) + 1);
memset(&(dir.Dir[index]), 0xFF, DENTRY_SIZE);
*(u16*)&dir.UpdateCounter = BE16(BE16(dir.UpdateCounter) + 1);
*(u16*)&bat.UpdateCounter = BE16(BE16(bat.UpdateCounter) + 1);
*PreviousDir = UpdatedDir;
if (PreviousDir == &dir )
{
CurrentDir = &dir;
PreviousDir = &dir_backup;
}
else
{
CurrentDir = &dir_backup;
PreviousDir = &dir;
}
memset(&(UpdatedDir.Dir[index]), 0xFF, DENTRY_SIZE);
*(u16*)&UpdatedDir.UpdateCounter = BE16(BE16(UpdatedDir.UpdateCounter) + 1);
*PreviousDir = UpdatedDir;
if (PreviousDir == &dir )
{
CurrentDir = &dir;
PreviousDir = &dir_backup;
}
else
{
CurrentDir = &dir_backup;
PreviousDir = &dir;
}
return SUCCESS;
/*
//error checking
u16 startingblock = 0;
for (int i = 0; i < DIRLEN; i++)
{
if (startingblock > BE16(dir.Dir[i].FirstBlock))
return DELETE_FAIL;
startingblock = BE16(dir.Dir[i].FirstBlock);
}
//backup the directory and bat (not really needed here but meh :P
dir_backup = dir;
bat_backup = bat;
//free the blocks
int blocks_left = BE16(dir.Dir[index].BlockCount);
*(u16*)&bat.LastAllocated = BE16(BE16(dir.Dir[index].FirstBlock) - 1);
u8 nextIndex = index + 1;
memset(&(dir.Dir[index]), 0xFF, DENTRY_SIZE);
while (nextIndex < DIRLEN)
{
DEntry tempDEntry;
GetDEntry(nextIndex, tempDEntry);
std::vector<GCMBlock> saveData;
u16 size = 0;
//Only get file data if it is a valid dir entry
if (BE16(tempDEntry.FirstBlock) != 0xFFFF)
{
*(u16*)&bat.FreeBlocks = BE16(BE16(bat.FreeBlocks) - BE16(tempDEntry.BlockCount));
size = DEntry_BlockCount(nextIndex);
if (size != 0xFFFF)
{
saveData.reserve(size);
switch (GetSaveData(nextIndex, saveData))
{
case NOMEMCARD:
break;
case FAIL:
return FAIL;
}
}
}
memset(&(dir.Dir[nextIndex]), 0xFF, DENTRY_SIZE);
//Only call import file if GetSaveData returns SUCCESS
if (saveData.size() == size)
{
ImportFile(tempDEntry, saveData, blocks_left);
}
nextIndex++;
}
//Added to clean up if removing last file
if (BE16(bat.LastAllocated) == (u16)4)
{
for (int j = 0; j < blocks_left; j++)
{
bat.Map[j] = 0x0000;
}
}
// increment update counter
*(u16*)&dir.UpdateCounter = BE16(BE16(dir.UpdateCounter) + 1);
*/
}
u32 GCMemcard::CopyFrom(const GCMemcard& source, u8 index)
@ -820,7 +795,7 @@ u32 GCMemcard::CopyFrom(const GCMemcard& source, u8 index)
case NOMEMCARD:
return NOMEMCARD;
default:
return ImportFile(tempDEntry, saveData, 0);
return ImportFile(tempDEntry, saveData);
}
}
@ -922,7 +897,7 @@ u32 GCMemcard::ImportGciInternal(FILE* gcih, const char *inputFile, const std::s
ret = WRITEFAIL;
}
else
ret = ImportFile(tempDEntry, saveData, 0);
ret = ImportFile(tempDEntry, saveData);
return ret;
}
@ -1053,7 +1028,7 @@ bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer) const
if (!m_valid)
return false;
int flags = dir.Dir[index].BIFlags;
int flags = CurrentDir->Dir[index].BIFlags;
// Timesplitters 2 is the only game that I see this in
// May be a hack
if (flags == 0xFB) flags = ~flags;
@ -1063,8 +1038,8 @@ bool GCMemcard::ReadBannerRGBA8(u8 index, u32* buffer) const
if (bnrFormat == 0)
return false;
u32 DataOffset = BE32(dir.Dir[index].ImageOffset);
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS;
u32 DataOffset = BE32(CurrentDir->Dir[index].ImageOffset);
u32 DataBlock = BE16(CurrentDir->Dir[index].FirstBlock) - MC_FST_BLOCKS;
if ((DataBlock > maxBlock) || (DataOffset == 0xFFFFFFFF))
{
@ -1098,17 +1073,17 @@ u32 GCMemcard::ReadAnimRGBA8(u8 index, u32* buffer, u8 *delays) const
// Sonic Heroes it the only game I have seen that tries to use a CI8 and RGB5A3 icon
int fmtCheck = 0;
int formats = BE16(dir.Dir[index].IconFmt);
int fdelays = BE16(dir.Dir[index].AnimSpeed);
int formats = BE16(CurrentDir->Dir[index].IconFmt);
int fdelays = BE16(CurrentDir->Dir[index].AnimSpeed);
int flags = dir.Dir[index].BIFlags;
int flags = CurrentDir->Dir[index].BIFlags;
// Timesplitters 2 is the only game that I see this in
// May be a hack
if (flags == 0xFB) flags = ~flags;
int bnrFormat = (flags&3);
u32 DataOffset = BE32(dir.Dir[index].ImageOffset);
u32 DataBlock = BE16(dir.Dir[index].FirstBlock) - MC_FST_BLOCKS;
u32 DataOffset = BE32(CurrentDir->Dir[index].ImageOffset);
u32 DataBlock = BE16(CurrentDir->Dir[index].FirstBlock) - MC_FST_BLOCKS;
if ((DataBlock > maxBlock) || (DataOffset == 0xFFFFFFFF))
{

View File

@ -157,6 +157,7 @@ private:
u16 Checksum_Inv; //0x1ffe 2 Inverse Checksum
} dir, dir_backup;
Directory *CurrentDir, *PreviousDir;
struct BlockAlloc {
u16 Checksum; //0x0000 2 Additive Checksum
u16 Checksum_Inv; //0x0002 2 Inverse Checksum
@ -164,7 +165,12 @@ private:
u8 FreeBlocks[2]; //0x0006 2 free Blocks
u8 LastAllocated[2];//0x0008 2 last allocated Block
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;
BlockAlloc *CurrentBat, *PreviousBat;
struct GCMC_Header
{
Header *hdr;
@ -219,9 +225,6 @@ public:
std::string GetSaveComment2(u8 index) const;
// Copies a DEntry from u8 index to DEntry& data
bool GetDEntry(u8 index, DEntry &dest) const;
u16 GetNextBlock(u16 Block) const;
u16 NextFreeBlock(u16 StartingBlock=MC_FST_BLOCKS) const;
bool ClearBlocks(u16 StartingBlock, u16 Length);
// assumes there's enough space in buffer
// old determines if function uses old or new method of copying data
@ -230,8 +233,7 @@ public:
u32 GetSaveData(u8 index, std::vector<GCMBlock> &saveBlocks) const;
// 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, int remove);
u32 ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks);
// delete a file from the directory
u32 RemoveFile(u8 index);

View File

@ -730,8 +730,8 @@ bool CMemcardManager::ReloadMemcard(const char *fileName, int card)
wxBlock.Printf(wxT("%10d"), blocks);
m_MemcardList[card]->SetItem(index,COLUMN_BLOCKS, wxBlock);
firstblock = memoryCard[card]->DEntry_FirstBlock(fileIndex);
if (firstblock == 0xFFFF) firstblock = 3; // to make firstblock -1
wxFirstBlock.Printf(wxT("%15d"), firstblock-4);
//if (firstblock == 0xFFFF) firstblock = 3; // to make firstblock -1
wxFirstBlock.Printf(wxT("%15d"), firstblock);
m_MemcardList[card]->SetItem(index, COLUMN_FIRSTBLOCK, wxFirstBlock);
m_MemcardList[card]->SetItem(index, COLUMN_ICON, wxEmptyString);