diff --git a/PKHeX/PKHeX.csproj b/PKHeX/PKHeX.csproj
index 4ac51cb68..807cdf50f 100644
--- a/PKHeX/PKHeX.csproj
+++ b/PKHeX/PKHeX.csproj
@@ -375,6 +375,7 @@
SplashScreen.cs
+
diff --git a/PKHeX/Saves/SAV3Colosseum.cs b/PKHeX/Saves/SAV3Colosseum.cs
index 77d7c4306..5b6285da1 100644
--- a/PKHeX/Saves/SAV3Colosseum.cs
+++ b/PKHeX/Saves/SAV3Colosseum.cs
@@ -325,7 +325,6 @@ namespace PKHeX
}
}
-
// Daycare Structure:
// 0x00 -- Occupied
// 0x01 -- Deposited Level
@@ -338,64 +337,4 @@ namespace PKHeX
public override void setDaycareEXP(int loc, int slot, uint EXP) { }
public override void setDaycareOccupied(int loc, int slot, bool occupied) { }
}
- internal static class BigEndian
- {
- internal static uint ToUInt32(byte[] data, int offset)
- {
- int val = 0;
- val |= data[offset + 0] << 24;
- val |= data[offset + 1] << 16;
- val |= data[offset + 2] << 8;
- val |= data[offset + 3] << 0;
- return (uint)val;
- }
- internal static ushort ToUInt16(byte[] data, int offset)
- {
- int val = 0;
- val |= data[offset + 0] << 8;
- val |= data[offset + 1] << 0;
- return (ushort)val;
- }
- internal static int ToInt32(byte[] data, int offset)
- {
- int val = 0;
- val |= data[offset + 0] << 24;
- val |= data[offset + 1] << 16;
- val |= data[offset + 2] << 8;
- val |= data[offset + 3] << 0;
- return val;
- }
- internal static short ToInt16(byte[] data, int offset)
- {
- int val = 0;
- val |= data[offset + 0] << 8;
- val |= data[offset + 1] << 0;
- return (short)val;
- }
- internal static byte[] GetBytes(int value)
- {
- return Invert(BitConverter.GetBytes(value));
- }
- internal static byte[] GetBytes(short value)
- {
- return Invert(BitConverter.GetBytes(value));
- }
- internal static byte[] GetBytes(uint value)
- {
- return Invert(BitConverter.GetBytes(value));
- }
- internal static byte[] GetBytes(ushort value)
- {
- return Invert(BitConverter.GetBytes(value));
- }
- private static byte[] Invert(byte[] data)
- {
- byte[] result = new byte[data.Length];
- int o = 0;
- int i = data.Length;
- while (o != data.Length)
- result[--i] = data[o++];
- return result;
- }
- }
}
diff --git a/PKHeX/Saves/SAV4BR.cs b/PKHeX/Saves/SAV4BR.cs
index bf209512d..ab448441f 100644
--- a/PKHeX/Saves/SAV4BR.cs
+++ b/PKHeX/Saves/SAV4BR.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.Linq;
using System.Text;
@@ -12,6 +11,7 @@ namespace PKHeX
public override string Filter => "PbrSaveData|*";
public override string Extension => "";
+ private const int SAVE_COUNT = 4;
public SAV4BR(byte[] data = null)
{
Data = data == null ? new byte[SaveUtil.SIZE_G4BR] : (byte[])data.Clone();
@@ -24,8 +24,7 @@ namespace PKHeX
Data = DecryptPBRSaveData(data);
// Detect active save
- if (Util.SwapEndianness(BitConverter.ToUInt32(Data, 0x1C004C)) >
- Util.SwapEndianness(BitConverter.ToUInt32(Data, 0x4C)))
+ if (BigEndian.ToUInt32(Data, 0x1C004C) > BigEndian.ToUInt32(Data, 0x4C))
{
byte[] tempData = new byte[0x1C0000];
Array.Copy(Data, 0, tempData, 0, 0x1C0000);
@@ -34,8 +33,8 @@ namespace PKHeX
}
SaveSlots = new List();
- SaveNames = new string[4];
- for (int i = 0; i < 4; i++)
+ SaveNames = new string[SAVE_COUNT];
+ for (int i = 0; i < SAVE_COUNT; i++)
{
if (BitConverter.ToUInt16(Data, 0x390 + 0x6FF00*i) != 0)
{
@@ -53,20 +52,20 @@ namespace PKHeX
resetBoxes();
}
- private readonly int SaveCount;
- public override byte[] Write(bool dsv = false)
+ private readonly int SaveCount; // TODO : unique save identification
+ public override byte[] Write(bool DSV)
{
setChecksums();
return EncryptPBRSaveData(Data);
}
// Configuration
- public override SaveFile Clone() { return new SAV4BR(Write()); }
+ public override SaveFile Clone() { return new SAV4BR(Write(DSV: false)); }
- public List SaveSlots;
- public string[] SaveNames;
+ public readonly List SaveSlots;
+ public readonly string[] SaveNames;
public int CurrentSlot;
- protected override int Box {
+ protected override int Box { // 4 save slots, data reading depends on current slot
get { return 0x978 + 0x6FF00*CurrentSlot; }
set { }
}
@@ -111,19 +110,13 @@ namespace PKHeX
return valid;
}
}
- public override string ChecksumInfo
- {
- get
- {
- return $"Checksums valid: {ChecksumsValid}.";
- }
- }
+ public override string ChecksumInfo => $"Checksums valid: {ChecksumsValid}.";
// Trainer Info
public override GameVersion Version { get { return GameVersion.BATREV; } protected set { } }
// Storage
- public override int getPartyOffset(int slot)
+ public override int getPartyOffset(int slot) // TODO
{
return -1;
}
@@ -131,23 +124,13 @@ namespace PKHeX
{
return Box + SIZE_STORED * box * 30;
}
- public override int CurrentBox
- {
- get { return 0; }
- set { /* This isn't a real field. */ }
- }
- public override int getBoxWallpaper(int box)
- {
- return 0;
- }
- public override string getBoxName(int box)
- {
- return $"BOX {box + 1}";
- }
- public override void setBoxName(int box, string value)
- {
- /* No custom box names here. */
- }
+
+ // Save file does not have Box Name / Wallpaper info
+ public override int CurrentBox { get { return 0; } set { } }
+ public override int getBoxWallpaper(int box) { return box; }
+ public override string getBoxName(int box) { return $"BOX {box + 1}"; }
+ public override void setBoxName(int box, string value) { }
+
public override PKM getPKM(byte[] data)
{
byte[] pkm = data.Take(SIZE_STORED).ToArray();
@@ -161,40 +144,24 @@ namespace PKHeX
protected override void setDex(PKM pkm) { }
- public override void setStoredSlot(PKM pkm, int offset, bool? trade = null, bool? dex = null)
- {
- if (pkm == null) return;
- if (pkm.GetType() != PKMType)
- throw new InvalidCastException($"PKM Format needs to be {PKMType} when setting to a Battle Revolution Save File.");
- if (trade ?? SetUpdatePKM)
- setPKM(pkm);
- if (dex ?? SetUpdateDex)
- setDex(pkm);
- byte[] data = pkm.EncryptedBoxData;
- setData(data, offset);
-
- Edited = true;
- }
-
public static byte[] DecryptPBRSaveData(byte[] input)
{
byte[] output = new byte[input.Length];
for (int base_ofs = 0; base_ofs < SaveUtil.SIZE_G4BR; base_ofs += 0x1C0000)
{
-
Array.Copy(input, base_ofs, output, base_ofs, 8);
ushort[] keys = new ushort[4];
for (int i = 0; i < keys.Length; i++)
- keys[i] = Util.SwapEndianness(BitConverter.ToUInt16(input, base_ofs + i * 2));
+ keys[i] = BigEndian.ToUInt16(input, base_ofs + i * 2);
for (int ofs = base_ofs + 8; ofs < base_ofs + 0x1C0000; ofs += 8)
{
for (int i = 0; i < keys.Length; i++)
{
- ushort val = Util.SwapEndianness(BitConverter.ToUInt16(input, ofs + i*2));
+ ushort val = BigEndian.ToUInt16(input, ofs + i*2);
val -= keys[i];
- BitConverter.GetBytes(Util.SwapEndianness(val)).CopyTo(output, ofs + i*2);
+ BigEndian.GetBytes(val).CopyTo(output, ofs + i*2);
}
ushort[] oldKeys = (ushort[])keys.Clone();
oldKeys[0] += 0x43;
@@ -210,25 +177,24 @@ namespace PKHeX
return output;
}
- public static byte[] EncryptPBRSaveData(byte[] input)
+ private static byte[] EncryptPBRSaveData(byte[] input)
{
byte[] output = new byte[input.Length];
for (int base_ofs = 0; base_ofs < SaveUtil.SIZE_G4BR; base_ofs += 0x1C0000)
{
-
Array.Copy(input, base_ofs, output, base_ofs, 8);
ushort[] keys = new ushort[4];
for (int i = 0; i < keys.Length; i++)
- keys[i] = Util.SwapEndianness(BitConverter.ToUInt16(input, base_ofs + i * 2));
+ keys[i] = BigEndian.ToUInt16(input, base_ofs + i * 2);
for (int ofs = base_ofs + 8; ofs < base_ofs + 0x1C0000; ofs += 8)
{
for (int i = 0; i < keys.Length; i++)
{
- ushort val = Util.SwapEndianness(BitConverter.ToUInt16(input, ofs + i * 2));
+ ushort val = BigEndian.ToUInt16(input, ofs + i * 2);
val += keys[i];
- BitConverter.GetBytes(Util.SwapEndianness(val)).CopyTo(output, ofs + i * 2);
+ BigEndian.GetBytes(val).CopyTo(output, ofs + i * 2);
}
ushort[] oldKeys = (ushort[])keys.Clone();
oldKeys[0] += 0x43;
@@ -249,15 +215,15 @@ namespace PKHeX
uint[] storedChecksums = new uint[16];
for (int i = 0; i < storedChecksums.Length; i++)
{
- storedChecksums[i] = Util.SwapEndianness(BitConverter.ToUInt32(input, checksum_offset + i*4));
- BitConverter.GetBytes((uint) 0).CopyTo(input, checksum_offset + i*4);
+ storedChecksums[i] = BigEndian.ToUInt32(input, checksum_offset + i*4);
+ BitConverter.GetBytes((uint)0).CopyTo(input, checksum_offset + i*4);
}
uint[] checksums = new uint[16];
for (int i = 0; i < len; i += 2)
{
- ushort val = Util.SwapEndianness(BitConverter.ToUInt16(input, offset + i));
+ ushort val = BigEndian.ToUInt16(input, offset + i);
for (int j = 0; j < 16; j++)
{
checksums[j] += (uint)((val >> j) & 1);
@@ -266,7 +232,7 @@ namespace PKHeX
for (int i = 0; i < storedChecksums.Length; i++)
{
- BitConverter.GetBytes(Util.SwapEndianness(storedChecksums[i])).CopyTo(input, checksum_offset + i*4);
+ BigEndian.GetBytes(storedChecksums[i]).CopyTo(input, checksum_offset + i*4);
}
return checksums.SequenceEqual(storedChecksums);
@@ -277,7 +243,7 @@ namespace PKHeX
uint[] storedChecksums = new uint[16];
for (int i = 0; i < storedChecksums.Length; i++)
{
- storedChecksums[i] = Util.SwapEndianness(BitConverter.ToUInt32(input, checksum_offset + i * 4));
+ storedChecksums[i] = BigEndian.ToUInt32(input, checksum_offset + i * 4);
BitConverter.GetBytes((uint)0).CopyTo(input, checksum_offset + i * 4);
}
@@ -285,7 +251,7 @@ namespace PKHeX
for (int i = 0; i < len; i += 2)
{
- ushort val = Util.SwapEndianness(BitConverter.ToUInt16(input, offset + i));
+ ushort val = BigEndian.ToUInt16(input, offset + i);
for (int j = 0; j < 16; j++)
{
checksums[j] += (uint)((val >> j) & 1);
@@ -294,13 +260,8 @@ namespace PKHeX
for (int i = 0; i < checksums.Length; i++)
{
- BitConverter.GetBytes(Util.SwapEndianness(checksums[i])).CopyTo(input, checksum_offset + i * 4);
+ BigEndian.GetBytes(checksums[i]).CopyTo(input, checksum_offset + i * 4);
}
}
-
- private void SwapBytes(byte[] input, int offset, int num_bytes)
- {
- input.Skip(offset).Take(num_bytes).Reverse().ToArray().CopyTo(input, offset);
- }
}
}
diff --git a/PKHeX/Saves/SaveFile.cs b/PKHeX/Saves/SaveFile.cs
index 0dc4f42da..4431602bb 100644
--- a/PKHeX/Saves/SaveFile.cs
+++ b/PKHeX/Saves/SaveFile.cs
@@ -373,7 +373,7 @@ namespace PKHeX
{
if (pkm == null) return;
if (pkm.GetType() != PKMType)
- throw new InvalidCastException($"PKM Format needs to be {PKMType} when setting to a Gen{Generation} Save File.");
+ throw new InvalidCastException($"PKM Format needs to be {PKMType} when setting to a {GetType().Name.Last()} Save File.");
if (trade ?? SetUpdatePKM)
setPKM(pkm);
if (dex ?? SetUpdateDex)
diff --git a/PKHeX/Util/BigEndian.cs b/PKHeX/Util/BigEndian.cs
new file mode 100644
index 000000000..35258012e
--- /dev/null
+++ b/PKHeX/Util/BigEndian.cs
@@ -0,0 +1,67 @@
+using System;
+
+namespace PKHeX
+{
+ internal static class BigEndian
+ {
+ internal static uint ToUInt32(byte[] data, int offset)
+ {
+ int val = 0;
+ val |= data[offset + 0] << 24;
+ val |= data[offset + 1] << 16;
+ val |= data[offset + 2] << 8;
+ val |= data[offset + 3] << 0;
+ return (uint)val;
+ }
+ internal static ushort ToUInt16(byte[] data, int offset)
+ {
+ int val = 0;
+ val |= data[offset + 0] << 8;
+ val |= data[offset + 1] << 0;
+ return (ushort)val;
+ }
+ internal static int ToInt32(byte[] data, int offset)
+ {
+ int val = 0;
+ val |= data[offset + 0] << 24;
+ val |= data[offset + 1] << 16;
+ val |= data[offset + 2] << 8;
+ val |= data[offset + 3] << 0;
+ return val;
+ }
+ internal static short ToInt16(byte[] data, int offset)
+ {
+ int val = 0;
+ val |= data[offset + 0] << 8;
+ val |= data[offset + 1] << 0;
+ return (short)val;
+ }
+
+ internal static byte[] GetBytes(int value)
+ {
+ return Invert(BitConverter.GetBytes(value));
+ }
+ internal static byte[] GetBytes(short value)
+ {
+ return Invert(BitConverter.GetBytes(value));
+ }
+ internal static byte[] GetBytes(uint value)
+ {
+ return Invert(BitConverter.GetBytes(value));
+ }
+ internal static byte[] GetBytes(ushort value)
+ {
+ return Invert(BitConverter.GetBytes(value));
+ }
+
+ private static byte[] Invert(byte[] data)
+ {
+ byte[] result = new byte[data.Length];
+ int o = 0;
+ int i = data.Length;
+ while (o != data.Length)
+ result[--i] = data[o++];
+ return result;
+ }
+ }
+}