diff --git a/PKHeX.Core/Saves/SAV1Stadium.cs b/PKHeX.Core/Saves/SAV1Stadium.cs
index 8353ebf1d..203f51942 100644
--- a/PKHeX.Core/Saves/SAV1Stadium.cs
+++ b/PKHeX.Core/Saves/SAV1Stadium.cs
@@ -52,6 +52,16 @@ public override byte[] SetString(string value, int maxLength, int PadToSize = 0,
public override int GetPartyOffset(int slot) => -1;
+ private readonly bool IsPairSwapped;
+
+ protected override byte[] GetFinalData()
+ {
+ var result = base.GetFinalData();
+ if (IsPairSwapped)
+ BigEndian.SwapBytes32(result = (byte[])result.Clone());
+ return result;
+ }
+
public override bool ChecksumsValid => GetBoxChecksumsValid();
protected override void SetChecksums() => SetBoxChecksums();
@@ -104,6 +114,12 @@ protected override PKM GetPKM(byte[] data)
public SAV1Stadium(byte[] data, bool japanese) : base(data)
{
Japanese = japanese;
+ var swap = StadiumUtil.IsMagicPresentSwap(data, TeamSize, MAGIC_POKE);
+ if (swap)
+ {
+ BigEndian.SwapBytes32(Data);
+ IsPairSwapped = true;
+ }
Box = 0xC000;
}
@@ -163,34 +179,20 @@ public override void WriteBoxSlot(PKM pkm, byte[] data, int offset)
base.WriteBoxSlot(pkm, Data, offset);
}
- private const int MAGIC_POKE = 0x454B4F50;
+ private const uint MAGIC_POKE = 0x454B4F50;
public static bool IsStadiumU(byte[] data)
{
if (data.Length != SaveUtil.SIZE_G1STAD)
return false;
-
- // Check footers of first few teams to see if the magic value is there.
- for (int i = 0; i < 10; i++)
- {
- if (BitConverter.ToUInt32(data, TeamSizeU - ListFooterSize + (i * TeamSizeU)) != MAGIC_POKE) // POKE
- return false;
- }
- return true;
+ return StadiumUtil.IsMagicPresentEither(data, TeamSizeU, MAGIC_POKE);
}
public static bool IsStadiumJ(byte[] data)
{
if (data.Length != SaveUtil.SIZE_G1STAD)
return false;
-
- // Check footers of first few teams to see if the magic value is there.
- for (int i = 0; i < 10; i++)
- {
- if (BitConverter.ToUInt32(data, TeamSizeJ - ListFooterSize + (i * TeamSizeJ)) != MAGIC_POKE) // POKE
- return false;
- }
- return true;
+ return StadiumUtil.IsMagicPresentEither(data, TeamSizeJ, MAGIC_POKE);
}
}
diff --git a/PKHeX.Core/Saves/SAV1StadiumJ.cs b/PKHeX.Core/Saves/SAV1StadiumJ.cs
index cfe16e4a4..4c97c2316 100644
--- a/PKHeX.Core/Saves/SAV1StadiumJ.cs
+++ b/PKHeX.Core/Saves/SAV1StadiumJ.cs
@@ -14,7 +14,7 @@ public class SAV1StadiumJ : SaveFile, ILangDeviantSave
// Required since PK1 logic comparing a save file assumes the save file can be U/J
public int SaveRevision => 0;
- public string SaveRevisionString => string.Empty;
+ public string SaveRevisionString => "0"; // so we're different from Japanese SAV1Stadium naming...
public bool Japanese => true;
public bool Korean => false;
@@ -54,6 +54,16 @@ public override byte[] SetString(string value, int maxLength, int PadToSize = 0,
public override int GetPartyOffset(int slot) => -1;
+ private readonly bool IsPairSwapped;
+
+ protected override byte[] GetFinalData()
+ {
+ var result = base.GetFinalData();
+ if (IsPairSwapped)
+ BigEndian.SwapBytes32(result = (byte[])result.Clone());
+ return result;
+ }
+
public override bool ChecksumsValid => GetBoxChecksumsValid();
protected override void SetChecksums() => SetBoxChecksums();
@@ -102,6 +112,12 @@ protected override PKM GetPKM(byte[] data)
public SAV1StadiumJ(byte[] data) : base(data)
{
+ var swap = StadiumUtil.IsMagicPresentSwap(data, TeamSizeJ, MAGIC_POKE);
+ if (swap)
+ {
+ BigEndian.SwapBytes32(Data);
+ IsPairSwapped = true;
+ }
Box = 0x2500;
}
@@ -156,20 +172,13 @@ public override void WriteBoxSlot(PKM pkm, byte[] data, int offset)
base.WriteBoxSlot(pkm, Data, offset);
}
- private const int MAGIC_POKE = 0x454B4F50;
+ private const uint MAGIC_POKE = 0x454B4F50;
public static bool IsStadiumJ(byte[] data)
{
if (data.Length != SaveUtil.SIZE_G1STADJ)
return false;
-
- // Check footers of first few teams to see if the magic value is there.
- for (int i = 0; i < 10; i++)
- {
- if (BitConverter.ToUInt32(data, TeamSizeJ - ListFooterSize + (i * TeamSizeJ)) != MAGIC_POKE) // POKE
- return false;
- }
- return true;
+ return StadiumUtil.IsMagicPresentEither(data, TeamSizeJ, MAGIC_POKE);
}
}
}
diff --git a/PKHeX.Core/Saves/Util/StadiumUtil.cs b/PKHeX.Core/Saves/Util/StadiumUtil.cs
new file mode 100644
index 000000000..53b64f53c
--- /dev/null
+++ b/PKHeX.Core/Saves/Util/StadiumUtil.cs
@@ -0,0 +1,48 @@
+using System;
+
+namespace PKHeX.Core
+{
+ public static class StadiumUtil
+ {
+ public static bool IsMagicPresentEither(byte[] data, int size, uint magic)
+ {
+ if (IsMagicPresent(data, size, magic))
+ return true;
+
+ if (IsMagicPresentSwap(data, size, magic))
+ return true;
+
+ return false;
+ }
+
+ public static bool IsMagicPresent(byte[] data, int size, uint magic)
+ {
+ // Check footers of first few teams to see if the magic value is there.
+ for (int i = 0; i < 10; i++)
+ {
+ if (BitConverter.ToUInt32(data, size - 6 + (i * size)) != magic)
+ return false;
+ }
+ return true;
+ }
+
+ public static bool IsMagicPresentSwap(byte[] data, int size, uint magic)
+ {
+ // Check footers of first few teams to see if the magic value is there.
+ var left = (ushort)magic;
+ var right = (ushort)(magic >> 16);
+ left = (ushort)((left >> 8) | (left << 8));
+ right = (ushort)((right >> 8) | (right << 8));
+
+ for (int i = 0; i < 10; i++)
+ {
+ var ofs = size - 6 + (i * size);
+ if (BitConverter.ToUInt16(data, ofs - 2) != left) // OP
+ return false;
+ if (BitConverter.ToUInt16(data, ofs + 4) != right) // EK
+ return false;
+ }
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/PKHeX.Core/Util/BigEndian.cs b/PKHeX.Core/Util/BigEndian.cs
index 73500594a..693596751 100644
--- a/PKHeX.Core/Util/BigEndian.cs
+++ b/PKHeX.Core/Util/BigEndian.cs
@@ -75,6 +75,24 @@ private static byte[] Invert(byte[] data)
return data;
}
+ ///
+ /// Swaps byte ordering in a byte array based on 32bit value writes.
+ ///
+ /// The is reversed in-place.
+ public static void SwapBytes32(byte[] data)
+ {
+ for (int i = 0; i < data.Length; i += 4)
+ {
+ byte tmp = data[0 + i];
+ data[0 + i] = data[3 + i];
+ data[3 + i] = tmp;
+
+ byte tmp1 = data[1 + i];
+ data[1 + i] = data[2 + i];
+ data[2 + i] = tmp1;
+ }
+ }
+
///
/// Returns a 32-bit signed integer converted from bytes in a Binary Coded Decimal format byte array.
///