Skip to content

Commit

Permalink
small optimizations
Browse files Browse the repository at this point in the history
Add ccitt method to checksum an existing array
reduce linq usage (faster save retrieval)

misc4 line endings?
  • Loading branch information
kwsch committed Jun 11, 2017
1 parent 43838a5 commit 21ab029
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 26 deletions.
8 changes: 6 additions & 2 deletions PKHeX.Core/Saves/SAV3RSBox.cs
Expand Up @@ -172,11 +172,15 @@ public override void setBoxName(int box, string value)
}
public override PKM getPKM(byte[] data)
{
return new PK3(data.Take(PKX.SIZE_3STORED).ToArray());
if (data.Length != PKX.SIZE_3STORED)
Array.Resize(ref data, PKX.SIZE_3STORED);
return new PK3(data);
}
public override byte[] decryptPKM(byte[] data)
{
return PKX.decryptArray3(data.Take(PKX.SIZE_3STORED).ToArray());
if (data.Length != PKX.SIZE_3STORED)
Array.Resize(ref data, PKX.SIZE_3STORED);
return PKX.decryptArray3(data);
}

protected override void setDex(PKM pkm) { }
Expand Down
12 changes: 6 additions & 6 deletions PKHeX.Core/Saves/SAV4.cs
Expand Up @@ -86,8 +86,8 @@ protected override void setChecksums()
if (c == null)
return;

BitConverter.GetBytes(SaveUtil.ccitt16(getData(c[0][0] + GBO, c[0][1] - c[0][0]))).CopyTo(Data, c[0][2] + GBO);
BitConverter.GetBytes(SaveUtil.ccitt16(getData(c[1][0] + SBO, c[1][1] - c[1][0]))).CopyTo(Data, c[1][2] + SBO);
BitConverter.GetBytes(SaveUtil.ccitt16(Data, c[0][0] + GBO, c[0][1] - c[0][0])).CopyTo(Data, c[0][2] + GBO);
BitConverter.GetBytes(SaveUtil.ccitt16(Data, c[1][0] + SBO, c[1][1] - c[1][0])).CopyTo(Data, c[1][2] + SBO);
}
public override bool ChecksumsValid
{
Expand All @@ -97,9 +97,9 @@ public override bool ChecksumsValid
if (c == null)
return false;

if (SaveUtil.ccitt16(getData(c[0][0] + GBO, c[0][1] - c[0][0])) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
if (SaveUtil.ccitt16(Data, c[0][0] + GBO, c[0][1] - c[0][0]) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
return false; // Small Fail
if (SaveUtil.ccitt16(getData(c[1][0] + SBO, c[1][1] - c[1][0])) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
if (SaveUtil.ccitt16(Data, c[1][0] + SBO, c[1][1] - c[1][0]) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
return false; // Large Fail

return true;
Expand All @@ -114,9 +114,9 @@ public override string ChecksumInfo
return "Unable to check Save File.";

string r = "";
if (SaveUtil.ccitt16(getData(c[0][0] + GBO, c[0][1] - c[0][0])) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
if (SaveUtil.ccitt16(Data, c[0][0] + GBO, c[0][1] - c[0][0]) != BitConverter.ToUInt16(Data, c[0][2] + GBO))
r += "Small block checksum is invalid" + Environment.NewLine;
if (SaveUtil.ccitt16(getData(c[1][0] + SBO, c[1][1] - c[1][0])) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
if (SaveUtil.ccitt16(Data, c[1][0] + SBO, c[1][1] - c[1][0]) != BitConverter.ToUInt16(Data, c[1][2] + SBO))
r += "Large block checksum is invalid" + Environment.NewLine;

return r.Length == 0 ? "Checksums valid." : r.TrimEnd();
Expand Down
34 changes: 22 additions & 12 deletions PKHeX.Core/Saves/SaveUtil.cs
Expand Up @@ -229,20 +229,21 @@ public static GameVersion getIsG3BOXSAV(byte[] data)
if (!new[] { SIZE_G3BOX, SIZE_G3BOXGCI }.Contains(data.Length))
return GameVersion.Invalid;

byte[] sav = data.Skip(data.Length - SIZE_G3BOX).Take(SIZE_G3BOX).ToArray();
byte[] sav = data;

// Verify first checksum
uint chk = 0; // initial value
var ofs = data.Length - SIZE_G3BOX + 0x2000;
for (int j = 0x4; j < 0x1FFC; j += 2)
{
chk += (ushort)(sav[0x2000 + j] << 8);
chk += sav[0x2000 + j + 1];
chk += (ushort)(sav[ofs + j] << 8);
chk += sav[ofs + j + 1];
}
ushort chkA = (ushort)chk;
ushort chkB = (ushort)(0xF004 - chkA);

ushort CHK_A = (ushort)((sav[0x2000] << 8) | sav[0x2001]);
ushort CHK_B = (ushort)((sav[0x2002] << 8) | sav[0x2003]);
ushort CHK_A = (ushort)((sav[ofs + 0] << 8) | sav[ofs + 1]);
ushort CHK_B = (ushort)((sav[ofs + 2] << 8) | sav[ofs + 3]);

return CHK_A == chkA && CHK_B == chkB ? GameVersion.RSBOX : GameVersion.Invalid;
}
Expand Down Expand Up @@ -295,11 +296,11 @@ public static GameVersion getIsG4SAV(byte[] data)
return GameVersion.Invalid;

// General Block Checksum
if (BitConverter.ToUInt16(data, 0xC0FE) == ccitt16(data.Take(0xC0EC).ToArray()))
if (BitConverter.ToUInt16(data, 0xC0FE) == ccitt16(data, 0, 0xC0EC))
return GameVersion.DP;
if (BitConverter.ToUInt16(data, 0xCF2A) == ccitt16(data.Take(0xCF18).ToArray()))
if (BitConverter.ToUInt16(data, 0xCF2A) == ccitt16(data, 0, 0xCF18))
return GameVersion.Pt;
if (BitConverter.ToUInt16(data, 0xF626) == ccitt16(data.Take(0xF618).ToArray()))
if (BitConverter.ToUInt16(data, 0xF626) == ccitt16(data, 0, 0xF618))
return GameVersion.HGSS;

// General Block Checksum is invalid, check for block identifiers
Expand Down Expand Up @@ -346,11 +347,11 @@ public static GameVersion getIsG5SAV(byte[] data)
return GameVersion.Invalid;

ushort chk1 = BitConverter.ToUInt16(data, SIZE_G5BW - 0x100 + 0x8C + 0xE);
ushort actual1 = ccitt16(data.Skip(SIZE_G5BW - 0x100).Take(0x8C).ToArray());
ushort actual1 = ccitt16(data, SIZE_G5BW - 0x100, 0x8C);
if (chk1 == actual1)
return GameVersion.BW;
ushort chk2 = BitConverter.ToUInt16(data, SIZE_G5B2W2 - 0x100 + 0x94 + 0xE);
ushort actual2 = ccitt16(data.Skip(SIZE_G5B2W2 - 0x100).Take(0x94).ToArray());
ushort actual2 = ccitt16(data, SIZE_G5B2W2 - 0x100, 0x94);
if (chk2 == actual2)
return GameVersion.B2W2;
return GameVersion.Invalid;
Expand Down Expand Up @@ -590,15 +591,19 @@ public static bool SizeValidSAV(int size)
// SAV Manipulation
/// <summary>Calculates the CRC16-CCITT checksum over an input byte array.</summary>
/// <param name="data">Input byte array</param>
/// <param name="start">Starting point for checksum</param>
/// <param name="length"></param>
/// <returns>Checksum</returns>
public static ushort ccitt16(byte[] data)
public static ushort ccitt16(byte[] data, int start, int length)
{
const ushort init = 0xFFFF;
const ushort poly = 0x1021;

ushort crc = init;
foreach (byte b in data)
int end = start + length;
for (int i = start; i < end; i++)
{
byte b = data[i];
crc ^= (ushort)(b << 8);
for (int j = 0; j < 8; j++)
{
Expand All @@ -611,6 +616,11 @@ public static ushort ccitt16(byte[] data)
return crc;
}

/// <summary>Calculates the CRC16-CCITT checksum over an input byte array.</summary>
/// <param name="data">Input byte array</param>
/// <returns>Checksum</returns>
public static ushort ccitt16(byte[] data) => ccitt16(data, 0, data.Length);

private static readonly ushort[] crc16 =
{
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
Expand Down
3 changes: 2 additions & 1 deletion PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs
Expand Up @@ -491,7 +491,8 @@ private void saveBF()
if (Prints[i] == 1 + Math.Sign((BitConverter.ToUInt16(SAV.Data, ofsPrints + (i << 1)) >> 1) - 1)) continue;
BitConverter.GetBytes(Prints[i] << 1).CopyTo(SAV.Data, ofsPrints + (i << 1));
}
if (HallStatUpdated) BitConverter.GetBytes(SaveUtil.ccitt16(SAV.Data.Skip(ofsHallStat).Take(0xBAE).ToArray())).CopyTo(SAV.Data, ofsHallStat + 0xBAE);
if (HallStatUpdated)
BitConverter.GetBytes(SaveUtil.ccitt16(SAV.Data, ofsHallStat, 0xBAE)).CopyTo(SAV.Data, ofsHallStat + 0xBAE);
}

private void setPrints()
Expand Down
5 changes: 1 addition & 4 deletions PKHeX.WinForms/Subforms/Save Editors/Gen5/SAV_CGearSkin.cs
Expand Up @@ -122,15 +122,12 @@ private void B_Save_Click(object sender, EventArgs e)
BitConverter.GetBytes(chk).CopyTo(SAV.Data, SAV.CGearDataOffset + bgdata.Length + 2);
BitConverter.GetBytes(chk).CopyTo(SAV.Data, SAV.CGearDataOffset + bgdata.Length + 0x100);

byte[] skinchkdata = SAV.Data.Skip(SAV.CGearDataOffset + bgdata.Length + 0x100).Take(4).ToArray();
ushort skinchkval = SaveUtil.ccitt16(skinchkdata);
ushort skinchkval = SaveUtil.ccitt16(SAV.Data, bgdata.Length + 0x100, 4);
BitConverter.GetBytes(skinchkval).CopyTo(SAV.Data, SAV.CGearDataOffset + bgdata.Length + 0x112);

// Indicate in the save file that data is present
BitConverter.GetBytes((ushort)0xC21E).CopyTo(SAV.Data, 0x19438);



SAV.Data[SAV.CGearInfoOffset + 0x26] = 1; // data present
BitConverter.GetBytes(chk).CopyTo(SAV.Data, SAV.CGearInfoOffset + 0x24);

Expand Down
2 changes: 1 addition & 1 deletion PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Link6.cs
Expand Up @@ -40,7 +40,7 @@ private void B_Save_Click(object sender, EventArgs e)
Array.Copy(LinkInfo.Data, 0, data, 0x1FF, LinkInfo.Data.Length);

// Fix Checksum just in case.
ushort ccitt = SaveUtil.ccitt16(data.Skip(0x200).Take(data.Length - 4 - 0x200).ToArray()); // [app,chk)
ushort ccitt = SaveUtil.ccitt16(data, 0x200, data.Length - 4 - 0x200); // [app,chk)
BitConverter.GetBytes(ccitt).CopyTo(data, data.Length - 4);

SAV.LinkBlock = data;
Expand Down

0 comments on commit 21ab029

Please sign in to comment.