From 39c3a0eea700231253ababe2c340dcb5967f41d0 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 16 Sep 2018 13:57:09 -0700 Subject: [PATCH] Rework sav3 version detect Might still be flaky for FRLG, but can now (99.99999999%) determine RS vs E... --- PKHeX.Core/Saves/SAV3.cs | 36 ++++++++++++++++++++++++------- PKHeX.Core/Saves/Util/SaveUtil.cs | 11 +--------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/PKHeX.Core/Saves/SAV3.cs b/PKHeX.Core/Saves/SAV3.cs index cb4b13056..b6db8871c 100644 --- a/PKHeX.Core/Saves/SAV3.cs +++ b/PKHeX.Core/Saves/SAV3.cs @@ -72,14 +72,6 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) BAK = (byte[])Data.Clone(); Exportable = !IsRangeEmpty(0, Data.Length); - if (data == null) - Version = GameVersion.FRLG; - else if (versionOverride != GameVersion.Any) - Version = versionOverride; - else Version = SaveUtil.GetIsG3SAV(Data); - if (Version == GameVersion.Invalid) - return; - int[] BlockOrder1 = GetBlockOrder(0); if (Data.Length > SaveUtil.SIZE_G3RAWHALF) { @@ -100,6 +92,13 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any) BlockOfs[i] = index < 0 ? int.MinValue : (index * SIZE_BLOCK) + ABO; } + if (data == null) + Version = GameVersion.FRLG; + else if (versionOverride != GameVersion.Any) + Version = versionOverride; + else + Version = GetVersion(Data, BlockOfs[0]); + // Set up PC data buffer beyond end of save file. Box = Data.Length; Array.Resize(ref Data, Data.Length + SIZE_RESERVED); // More than enough empty space. @@ -197,6 +196,27 @@ private int GetActiveSaveIndex(int[] BlockOrder1, int[] BlockOrder2) return count1 > count2 ? 0 : 1; } + public static GameVersion GetVersion(byte[] data, int block0Ofs) + { + uint GameCode = BitConverter.ToUInt32(data, block0Ofs + 0xAC); + switch (GameCode) + { + case 1: return GameVersion.FRLG; // fixed value + case 0: return GameVersion.RS; // no battle tower record data + case uint.MaxValue: return GameVersion.Unknown; // what a hack + default: + // Ruby doesn't set data as far down as Emerald. + // 00 FF 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 + // ^ byte pattern in Emerald saves, is all zero in Ruby/Sapphire as far as I can tell. + // Some saves have had data @ 0x550 + if (BitConverter.ToUInt64(data, block0Ofs + 0xEE0) != 0) + return GameVersion.E; + if (BitConverter.ToUInt64(data, block0Ofs + 0xEE8) != 0) + return GameVersion.E; + return GameVersion.RS; + } + } + protected override byte[] Write(bool DSV) { // Copy Box data back diff --git a/PKHeX.Core/Saves/Util/SaveUtil.cs b/PKHeX.Core/Saves/Util/SaveUtil.cs index f1764836b..e5e8b7326 100644 --- a/PKHeX.Core/Saves/Util/SaveUtil.cs +++ b/PKHeX.Core/Saves/Util/SaveUtil.cs @@ -237,16 +237,7 @@ internal static GameVersion GetIsG3SAV(byte[] data) continue; if (BlockOrder.Count(v => v == 0) == BlockOrder.Length) continue; - uint GameCode = BitConverter.ToUInt32(data, (Block0 * 0x1000) + 0xAC + ofs); - switch (GameCode) - { - case 0: return GameVersion.RS; - case 1: return GameVersion.FRLG; - case uint.MaxValue: return GameVersion.Unknown; // what a hack - default: return BitConverter.ToUInt32(data, (Block0 * 0x1000) + 0x1F4 + ofs) == 0 - ? GameVersion.RS - : GameVersion.E; - } + return SAV3.GetVersion(data, (0x1000 * Block0) + ofs); } return GameVersion.Invalid; }