Rework sav3 version detect

Might still be flaky for FRLG, but can now (99.99999999%) determine RS
vs E...
This commit is contained in:
Kurt 2018-09-16 13:57:09 -07:00
parent 668b8611d5
commit 39c3a0eea7
2 changed files with 29 additions and 18 deletions

View File

@ -72,14 +72,6 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any)
BAK = (byte[])Data.Clone();
Exportable = !IsRangeEmpty(0, Data.Length);
if (data == null)
Version = GameVersion.FRLG;
else if (versionOverride != GameVersion.Any)
Version = versionOverride;
else Version = SaveUtil.GetIsG3SAV(Data);
if (Version == GameVersion.Invalid)
return;
int[] BlockOrder1 = GetBlockOrder(0);
if (Data.Length > SaveUtil.SIZE_G3RAWHALF)
{
@ -100,6 +92,13 @@ public SAV3(byte[] data = null, GameVersion versionOverride = GameVersion.Any)
BlockOfs[i] = index < 0 ? int.MinValue : (index * SIZE_BLOCK) + ABO;
}
if (data == null)
Version = GameVersion.FRLG;
else if (versionOverride != GameVersion.Any)
Version = versionOverride;
else
Version = GetVersion(Data, BlockOfs[0]);
// Set up PC data buffer beyond end of save file.
Box = Data.Length;
Array.Resize(ref Data, Data.Length + SIZE_RESERVED); // More than enough empty space.
@ -197,6 +196,27 @@ private int GetActiveSaveIndex(int[] BlockOrder1, int[] BlockOrder2)
return count1 > count2 ? 0 : 1;
}
public static GameVersion GetVersion(byte[] data, int block0Ofs)
{
uint GameCode = BitConverter.ToUInt32(data, block0Ofs + 0xAC);
switch (GameCode)
{
case 1: return GameVersion.FRLG; // fixed value
case 0: return GameVersion.RS; // no battle tower record data
case uint.MaxValue: return GameVersion.Unknown; // what a hack
default:
// Ruby doesn't set data as far down as Emerald.
// 00 FF 00 00 00 00 00 00 00 FF 00 00 00 00 00 00
// ^ byte pattern in Emerald saves, is all zero in Ruby/Sapphire as far as I can tell.
// Some saves have had data @ 0x550
if (BitConverter.ToUInt64(data, block0Ofs + 0xEE0) != 0)
return GameVersion.E;
if (BitConverter.ToUInt64(data, block0Ofs + 0xEE8) != 0)
return GameVersion.E;
return GameVersion.RS;
}
}
protected override byte[] Write(bool DSV)
{
// Copy Box data back

View File

@ -237,16 +237,7 @@ internal static GameVersion GetIsG3SAV(byte[] data)
continue;
if (BlockOrder.Count(v => v == 0) == BlockOrder.Length)
continue;
uint GameCode = BitConverter.ToUInt32(data, (Block0 * 0x1000) + 0xAC + ofs);
switch (GameCode)
{
case 0: return GameVersion.RS;
case 1: return GameVersion.FRLG;
case uint.MaxValue: return GameVersion.Unknown; // what a hack
default: return BitConverter.ToUInt32(data, (Block0 * 0x1000) + 0x1F4 + ofs) == 0
? GameVersion.RS
: GameVersion.E;
}
return SAV3.GetVersion(data, (0x1000 * Block0) + ofs);
}
return GameVersion.Invalid;
}