From e8644280a129bafc5f5b0ced5f5bed2d8506980f Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 25 Jul 2018 16:00:52 -0700 Subject: [PATCH] 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 https://github.com/kwsch/PKHeX/commit/5f39118b8ab3d88396dacec79ae0576cc0d4c03c Thanks @Filo97 ! --- PKHeX.Core/Saves/SAV4.cs | 77 ++++++++++++++++++++++-------------- PKHeX.Core/Saves/SaveFile.cs | 5 ++- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/PKHeX.Core/Saves/SAV4.cs b/PKHeX.Core/Saves/SAV4.cs index 48bbae660..bd82769ac 100644 --- a/PKHeX.Core/Saves/SAV4.cs +++ b/PKHeX.Core/Saves/SAV4.cs @@ -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) diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs index 3d79ef2eb..8320d0563 100644 --- a/PKHeX.Core/Saves/SaveFile.cs +++ b/PKHeX.Core/Saves/SaveFile.cs @@ -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; }