Force writeback on addition to uninitialized data

Adding an entity to an uninitialized save's box data will force all data to be flushed unless the final destination was (initially zeroed and has no slots to set).
This commit is contained in:
Kurt 2024-05-13 19:39:37 -05:00
parent 0836d3c670
commit ca85fba061
2 changed files with 37 additions and 6 deletions

View file

@ -45,7 +45,7 @@ public static class PokeList1
/// <param name="input">List header</param>
/// <param name="capacity">Count of slots allowed in the list</param>
/// <param name="lerp">Offset jump between slot indexes; used to parse multi-single lists instead of a multi-list.</param>
private static int CountPresent(ReadOnlySpan<byte> input, int capacity, int lerp = 0)
public static int CountPresent(ReadOnlySpan<byte> input, int capacity, int lerp = 0)
{
var count = 0;
for (int i = 0; i < capacity; i++)

View file

@ -144,23 +144,28 @@ public sealed class SAV1 : SaveFile, ILangDeviantSave, IEventFlagArray, IEventWo
protected override byte[] GetFinalData()
{
bool anyBoxPresent = false;
int boxListLength = SIZE_BOX_LIST;
var boxSlotCount = BoxSlotCount;
bool boxInitialized = BoxesInitialized;
var current = CurrentBox;
if (!boxInitialized)
{
// Check if any box has content in it.
bool newContent = AnyBoxSlotSpeciesPresent(current, boxSlotCount);
if (newContent)
BoxesInitialized = boxInitialized = true;
}
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);
var src = GetUnpackedBoxSpan(i);
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
{
@ -184,6 +189,32 @@ public sealed class SAV1 : SaveFile, ILangDeviantSave, IEventFlagArray, IEventWo
return Data;
}
private Span<byte> GetUnpackedBoxSpan(int box)
{
var size = SIZE_BOX_AS_SINGLES;
return BoxBuffer.Slice(box * size, size);
}
private bool AnyBoxSlotSpeciesPresent(int current, int boxSlotCount)
{
bool newContent = false;
for (int i = 0; i < BoxCount; i++)
{
if (i == current) // Exclude current box in the check.
continue;
var src = GetUnpackedBoxSpan(i);
int count = PokeList1.CountPresent(src, boxSlotCount);
if (count == 0)
continue;
newContent = true;
break;
}
return newContent;
}
private int GetBoxRawDataOffset(int box)
{
if (box < BoxCount / 2)