GCMemcard: fix edge case of adding to a fragmented memcard.

allocates last block of memcard, and then wraps around, instead of attempting to write past the end of the card
This commit is contained in:
LPFaint99 2014-05-01 12:21:48 -07:00
parent 557c3db462
commit b549ec70b4
2 changed files with 6 additions and 5 deletions

View File

@ -554,11 +554,12 @@ u16 GCMemcard::BlockAlloc::GetNextBlock(u16 Block) const
return Common::swap16(Map[Block-MC_FST_BLOCKS]); return Common::swap16(Map[Block-MC_FST_BLOCKS]);
} }
u16 GCMemcard::BlockAlloc::NextFreeBlock(u16 StartingBlock) const u16 GCMemcard::BlockAlloc::NextFreeBlock(u16 MaxBlock, u16 StartingBlock) const
{ {
if (FreeBlocks) if (FreeBlocks)
{ {
for (u16 i = StartingBlock; i < BAT_SIZE; ++i) MaxBlock = std::min<u16>(MaxBlock, BAT_SIZE);
for (u16 i = StartingBlock; i < MaxBlock; ++i)
if (Map[i-MC_FST_BLOCKS] == 0) if (Map[i-MC_FST_BLOCKS] == 0)
return i; return i;
@ -638,7 +639,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks)
} }
// find first free data block // find first free data block
u16 firstBlock = CurrentBat->NextFreeBlock(BE16(CurrentBat->LastAllocated)); u16 firstBlock = CurrentBat->NextFreeBlock(maxBlock - MC_FST_BLOCKS, BE16(CurrentBat->LastAllocated));
if (firstBlock == 0xFFFF) if (firstBlock == 0xFFFF)
return OUTOFBLOCKS; return OUTOFBLOCKS;
Directory UpdatedDir = *CurrentDir; Directory UpdatedDir = *CurrentDir;
@ -683,7 +684,7 @@ u32 GCMemcard::ImportFile(DEntry& direntry, std::vector<GCMBlock> &saveBlocks)
if (i == fileBlocks-1) if (i == fileBlocks-1)
nextBlock = 0xFFFF; nextBlock = 0xFFFF;
else else
nextBlock = UpdatedBat.NextFreeBlock(firstBlock+1); nextBlock = UpdatedBat.NextFreeBlock(maxBlock - MC_FST_BLOCKS, firstBlock + 1);
UpdatedBat.Map[firstBlock - MC_FST_BLOCKS] = BE16(nextBlock); UpdatedBat.Map[firstBlock - MC_FST_BLOCKS] = BE16(nextBlock);
UpdatedBat.LastAllocated = BE16(firstBlock); UpdatedBat.LastAllocated = BE16(firstBlock);
firstBlock = nextBlock; firstBlock = nextBlock;

View File

@ -158,7 +158,7 @@ private:
u16 LastAllocated; //0x0008 2 Last allocated Block u16 LastAllocated; //0x0008 2 Last allocated Block
u16 Map[BAT_SIZE]; //0x000a 0x1ff8 Map of allocated Blocks u16 Map[BAT_SIZE]; //0x000a 0x1ff8 Map of allocated Blocks
u16 GetNextBlock(u16 Block) const; u16 GetNextBlock(u16 Block) const;
u16 NextFreeBlock(u16 StartingBlock=MC_FST_BLOCKS) const; u16 NextFreeBlock(u16 MaxBlock, u16 StartingBlock = MC_FST_BLOCKS) const;
bool ClearBlocks(u16 StartingBlock, u16 Length); bool ClearBlocks(u16 StartingBlock, u16 Length);
} bat,bat_backup; } bat,bat_backup;