SAV1: Don't reference prior-save boxdata

If the boxes are not initialized, skip reading of box data
If the boxes are empty when saving, don't write if {dest 0} or {boxes uninitialized} to retain old data.
If the boxes have any slots when saving, set the flag that boxdata is good.

Remove flag from SAV2, game is different from SAV1. Only use the boxdata, just mirror to CurrentBox data as Stadium only looks at boxdata.
This commit is contained in:
Kurt 2024-05-13 17:41:23 -05:00
parent 3dc84d6a39
commit 215f892f11
3 changed files with 25 additions and 20 deletions

View File

@ -204,14 +204,15 @@ public static void Unpack(ReadOnlySpan<byte> input, Span<byte> output, int strin
/// <param name="stringLength">Trainer and Nickname string length</param>
/// <param name="capacity">Count of slots allowed in the list</param>
/// <param name="isParty">List stores party stats for each entity</param>
public static bool MergeSingles(ReadOnlySpan<byte> input, Span<byte> output, int stringLength, int capacity, bool isParty)
/// <param name="isDestInitialized">True if the destination list is initialized</param>
public static bool MergeSingles(ReadOnlySpan<byte> input, Span<byte> output, int stringLength, int capacity, bool isParty, bool isDestInitialized = true)
{
// Collect the count of set slots
var jp = IsJapaneseString(stringLength);
var size = GetListLengthSingle(jp);
int count = CountPresent(input, capacity, size);
if (count == 0 && !output.ContainsAnyExcept<byte>(0))
if (count == 0 && (!isDestInitialized || !output.ContainsAnyExcept<byte>(0)))
return false; // No need to merge if all empty and dest is not initialized.
output[0] = (byte)count; // ensure written list is valid

View File

@ -75,20 +75,25 @@ private void Initialize(GameVersion versionOverride)
Box = 0;
Party = GetPartyOffset(0);
// Stash boxes after the save file's end.
int stored = SIZE_BOX_LIST;
var capacity = BoxSlotCount;
for (int i = 0; i < BoxCount; i++)
var current = CurrentBox;
if (BoxesInitialized) // Current box has flushed to box storage at least once, box contents are trustworthy.
{
int ofs = GetBoxRawDataOffset(i);
var src = Data.AsSpan(ofs, stored);
var dest = BoxBuffer[(i * SIZE_BOX_AS_SINGLES)..];
PokeList1.Unpack(src, dest, StringLength, capacity, false);
for (int i = 0; i < BoxCount; i++)
{
if (i == current)
continue; // Use the current box data instead, loaded a little later.
int ofs = GetBoxRawDataOffset(i);
var src = Data.AsSpan(ofs, stored);
var dest = BoxBuffer[(i * SIZE_BOX_AS_SINGLES)..];
PokeList1.Unpack(src, dest, StringLength, capacity, false);
}
}
if (CurrentBox < BoxCount) // Load Current Box
if (current < BoxCount) // Load Current Box
{
var src = Data.AsSpan(Offsets.CurrentBox, stored);
var dest = BoxBuffer[(CurrentBox * SIZE_BOX_AS_SINGLES)..];
var dest = BoxBuffer[(current * SIZE_BOX_AS_SINGLES)..];
PokeList1.Unpack(src, dest, StringLength, capacity, false);
}
@ -139,18 +144,23 @@ public void SetEventFlag(int flagNumber, bool value)
protected override byte[] GetFinalData()
{
bool anyBoxPresent = false;
int boxListLength = SIZE_BOX_LIST;
var boxSlotCount = BoxSlotCount;
bool boxInitialized = BoxesInitialized;
for (int i = 0; i < BoxCount; i++)
{
int ofs = GetBoxRawDataOffset(i);
var dest = Data.AsSpan(ofs, boxListLength);
var src = BoxBuffer.Slice(i * SIZE_BOX_AS_SINGLES, SIZE_BOX_AS_SINGLES);
bool written = PokeList1.MergeSingles(src, dest, StringLength, boxSlotCount, false);
bool written = PokeList1.MergeSingles(src, dest, StringLength, boxSlotCount, false, boxInitialized);
if (written && i == CurrentBox)
dest.CopyTo(Data.AsSpan(Offsets.CurrentBox));
anyBoxPresent |= written;
}
if (anyBoxPresent)
BoxesInitialized = true; // box data has been flushed at least once
// Write Party
{
@ -446,7 +456,7 @@ public override int CurrentBox
set => Data[Offsets.CurrentBoxIndex] = (byte)((Data[Offsets.CurrentBoxIndex] & 0x80) | (value & 0x7F));
}
public bool CurrentBoxChanged
public bool BoxesInitialized
{
get => (Data[Offsets.CurrentBoxIndex] & 0x80) != 0;
set => Data[Offsets.CurrentBoxIndex] = (byte)((Data[Offsets.CurrentBoxIndex] & 0x7F) | (byte)(value ? 0x80 : 0));

View File

@ -587,14 +587,8 @@ public override int PartyCount
public override int CurrentBox
{
get => Data[Offsets.CurrentBoxIndex] & 0x7F;
set => Data[Offsets.CurrentBoxIndex] = (byte)((Data[Offsets.CurrentBoxIndex] & 0x80) | (value & 0x7F));
}
public bool CurrentBoxChanged
{
get => (Data[Offsets.CurrentBoxIndex] & 0x80) != 0;
set => Data[Offsets.CurrentBoxIndex] = (byte)((Data[Offsets.CurrentBoxIndex] & 0x7F) | (byte)(value ? 0x80 : 0));
get => Data[Offsets.CurrentBoxIndex];
set => Data[Offsets.CurrentBoxIndex] = (byte)value;
}
public string GetBoxName(int box)