using System; using static System.Buffers.Binary.BinaryPrimitives; namespace PKHeX.Core; /// /// Finds the index of the most recent save block for blocks. /// public static class SAV4BlockDetection { private const int First = 0; private const int Second = 1; private const int Same = 2; /// /// Compares the footers of the two blocks to determine which is newest. /// /// 0=Primary, 1=Secondary. public static int CompareFooters(ReadOnlySpan data, int offset1, int offset2) { // Major Counters var major1 = ReadUInt32LittleEndian(data[offset1..]); var major2 = ReadUInt32LittleEndian(data[offset2..]); var result1 = CompareCounters(major1, major2); if (result1 != Same) return result1; // Minor Counters var minor1 = ReadUInt32LittleEndian(data[(offset1 + 4)..]); var minor2 = ReadUInt32LittleEndian(data[(offset2 + 4)..]); var result2 = CompareCounters(minor1, minor2); return result2 == Second ? Second : First; // Same -> First, shouldn't happen for valid saves. } private static int CompareCounters(uint counter1, uint counter2) { // Uninitialized -- only continue if a rollover case (humanly impossible) if (counter1 == uint.MaxValue && counter2 != uint.MaxValue - 1) return Second; if (counter2 == uint.MaxValue && counter1 != uint.MaxValue - 1) return First; // Different if (counter1 > counter2) return First; if (counter1 < counter2) return Second; return Same; } }