Update sav4 block detect logic

#2070
desmume inits a savefile to FFFFFF... others instead init to 00's.
check both init states, add IsRangeAll method

5f39118b8a

Thanks @Filo97 !
This commit is contained in:
Kurt
2018-07-25 16:00:52 -07:00
parent 609e6b4c43
commit e8644280a1
2 changed files with 50 additions and 32 deletions

View File

@@ -27,8 +27,8 @@ public SAV4(byte[] data = null, GameVersion versionOverride = GameVersion.Any)
if (Version == GameVersion.Invalid)
return;
GetActiveGeneralBlock();
GetActiveStorageBlock();
generalBlock = GetActiveGeneralBlock();
storageBlock = GetActiveStorageBlock();
GetSAVOffsets();
switch (Version)
@@ -129,51 +129,68 @@ public override string ChecksumInfo
}
// Blocks & Offsets
private int generalBlock = -1; // Small Block
private int storageBlock = -1; // Big Block
private int hofBlock = -1; // Hall of Fame Block
private readonly int generalBlock = -1; // Small Block
private readonly int storageBlock = -1; // Big Block
private readonly int hofBlock = -1; // Hall of Fame Block
private int SBO => 0x40000 * storageBlock;
public int GBO => 0x40000 * generalBlock;
private int HBO => 0x40000 * hofBlock;
private void GetActiveGeneralBlock()
private int GetActiveGeneralBlock()
{
if (Version < 0)
return;
int ofs = 0;
return -1;
// Check to see if the save is initialized completely
// if the block is not initialized, fall back to the other save.
if (GetData(0x00000, 10).All(z => z == 0xFF))
{ generalBlock = 1; return; }
if (GetData(0x40000, 10).All(z => z == 0xFF))
{ generalBlock = 0; return; }
if (IsRangeAll(0x00000, 10, 0) || IsRangeAll(0x00000, 10, 0xFF))
return 1;
if (IsRangeAll(0x40000, 10, 0) || IsRangeAll(0x40000, 10, 0xFF))
return 0;
// Check SaveCount for current save
if (Version == GameVersion.DP) ofs = 0xC0F0; // DP
else if (Version == GameVersion.Pt) ofs = 0xCF1C; // PT
else if (Version == GameVersion.HGSS) ofs = 0xF618; // HGSS
generalBlock = BitConverter.ToUInt16(Data, ofs) >= BitConverter.ToUInt16(Data, ofs + 0x40000) ? 0 : 1;
int ofs = GetActiveBlockSaveCounterOffset();
bool first = BitConverter.ToUInt16(Data, ofs) >= BitConverter.ToUInt16(Data, ofs + 0x40000);
return first ? 0 : 1;
}
private void GetActiveStorageBlock()
private int GetActiveStorageBlock()
{
if (Version < 0)
return;
int ofs = 0;
// Check SaveCount for current save
if (Version == GameVersion.DP) ofs = 0x1E2D0; // DP
else if (Version == GameVersion.Pt) ofs = 0x1F100; // PT
else if (Version == GameVersion.HGSS) ofs = 0x21A00; // HGSS
return -1;
// Check to see if the save is initialized completely
// if the block is not initialized, fall back to the other save.
if (GetData(ofs + 0x00000, 10).All(z => z == 0xFF))
{ storageBlock = 1; return; }
if (GetData(ofs + 0x40000, 10).All(z => z == 0xFF))
{ storageBlock = 0; return; }
if (IsRangeAll(0x00000, 10, 0) || IsRangeAll(0x00000, 10, 0xFF))
return 1;
if (IsRangeAll(0x40000, 10, 0) || IsRangeAll(0x40000, 10, 0xFF))
return 0;
storageBlock = BitConverter.ToUInt16(Data, ofs) >= BitConverter.ToUInt16(Data, ofs + 0x40000) ? 0 : 1;
int ofs = GetStorageBlockSaveCounterOffset();
bool first = BitConverter.ToUInt16(Data, ofs) >= BitConverter.ToUInt16(Data, ofs + 0x40000);
return first ? 0 : 1;
}
private int GetActiveBlockSaveCounterOffset()
{
switch (Version)
{
case GameVersion.DP: return 0xC0F0;
case GameVersion.Pt: return 0xCF1C;
case GameVersion.HGSS: return 0xF618;
default: return -1;
}
}
private int GetStorageBlockSaveCounterOffset()
{
switch (Version)
{
case GameVersion.DP: return 0x1E2D0;
case GameVersion.Pt: return 0x1F100;
case GameVersion.HGSS: return 0x21A00;
default: return -1;
}
}
private void GetSAVOffsets()
{
if (Version < 0)

View File

@@ -760,10 +760,11 @@ public void SetData(byte[] input, int Offset)
input.CopyTo(Data, Offset);
Edited = true;
}
public bool IsRangeEmpty(int Offset, int Length)
public bool IsRangeEmpty(int Offset, int Length) => IsRangeAll(Offset, Length, 0);
public bool IsRangeAll(int Offset, int Length, int value)
{
for (int i = Offset; i < Offset + Length; i++)
if (Data[i] != 0)
if (Data[i] != value)
return false;
return true;
}