mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-17 05:48:44 +00:00
Add automatic byteswap
This commit is contained in:
parent
ee207a3fda
commit
2c8e0bc8f7
4 changed files with 104 additions and 27 deletions
|
@ -52,6 +52,16 @@ namespace PKHeX.Core
|
|||
|
||||
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 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace PKHeX.Core
|
|||
|
||||
// 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 @@ namespace PKHeX.Core
|
|||
|
||||
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 @@ namespace PKHeX.Core
|
|||
|
||||
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 @@ namespace PKHeX.Core
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
48
PKHeX.Core/Saves/Util/StadiumUtil.cs
Normal file
48
PKHeX.Core/Saves/Util/StadiumUtil.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,6 +75,24 @@ namespace PKHeX.Core
|
|||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Swaps byte ordering in a byte array based on 32bit value writes.
|
||||
/// </summary>
|
||||
/// <remarks>The <see cref="data"/> is reversed in-place.</remarks>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a 32-bit signed integer converted from bytes in a Binary Coded Decimal format byte array.
|
||||
/// </summary>
|
||||
|
|
Loading…
Add table
Reference in a new issue