mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-23 16:27:47 +01:00
Introduce Identifiers and strong entry types for each meta manipulation and use them in the manipulations.
This commit is contained in:
parent
ceed8531af
commit
2e9f184454
27 changed files with 533 additions and 163 deletions
|
|
@ -2,6 +2,7 @@ using Penumbra.GameData.Enums;
|
|||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.String.Functions;
|
||||
|
||||
namespace Penumbra.Meta.Files;
|
||||
|
|
@ -17,10 +18,10 @@ public sealed unsafe class CmpFile : MetaBaseFile
|
|||
|
||||
private const int RacialScalingStart = 0x2A800;
|
||||
|
||||
public float this[SubRace subRace, RspAttribute attribute]
|
||||
public RspEntry this[SubRace subRace, RspAttribute attribute]
|
||||
{
|
||||
get => *(float*)(Data + RacialScalingStart + ToRspIndex(subRace) * RspData.ByteSize + (int)attribute * 4);
|
||||
set => *(float*)(Data + RacialScalingStart + ToRspIndex(subRace) * RspData.ByteSize + (int)attribute * 4) = value;
|
||||
get => *(RspEntry*)(Data + RacialScalingStart + ToRspIndex(subRace) * RspData.ByteSize + (int)attribute * 4);
|
||||
set => *(RspEntry*)(Data + RacialScalingStart + ToRspIndex(subRace) * RspData.ByteSize + (int)attribute * 4) = value;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
|
|
@ -39,10 +40,10 @@ public sealed unsafe class CmpFile : MetaBaseFile
|
|||
Reset();
|
||||
}
|
||||
|
||||
public static float GetDefault(MetaFileManager manager, SubRace subRace, RspAttribute attribute)
|
||||
public static RspEntry GetDefault(MetaFileManager manager, SubRace subRace, RspAttribute attribute)
|
||||
{
|
||||
var data = (byte*)manager.CharacterUtility.DefaultResource(InternalIndex).Address;
|
||||
return *(float*)(data + RacialScalingStart + ToRspIndex(subRace) * RspData.ByteSize + (int)attribute * 4);
|
||||
return *(RspEntry*)(data + RacialScalingStart + ToRspIndex(subRace) * RspData.ByteSize + (int)attribute * 4);
|
||||
}
|
||||
|
||||
private static int ToRspIndex(SubRace subRace)
|
||||
|
|
|
|||
|
|
@ -34,26 +34,26 @@ public sealed unsafe class EstFile : MetaBaseFile
|
|||
Removed,
|
||||
}
|
||||
|
||||
public ushort this[GenderRace genderRace, ushort setId]
|
||||
public EstEntry this[GenderRace genderRace, PrimaryId setId]
|
||||
{
|
||||
get
|
||||
{
|
||||
var (idx, exists) = FindEntry(genderRace, setId);
|
||||
if (!exists)
|
||||
return 0;
|
||||
return EstEntry.Zero;
|
||||
|
||||
return *(ushort*)(Data + EntryDescSize * (Count + 1) + EntrySize * idx);
|
||||
return *(EstEntry*)(Data + EntryDescSize * (Count + 1) + EntrySize * idx);
|
||||
}
|
||||
set => SetEntry(genderRace, setId, value);
|
||||
}
|
||||
|
||||
private void InsertEntry(int idx, GenderRace genderRace, ushort setId, ushort skeletonId)
|
||||
private void InsertEntry(int idx, GenderRace genderRace, PrimaryId setId, EstEntry skeletonId)
|
||||
{
|
||||
if (Length < Size + EntryDescSize + EntrySize)
|
||||
ResizeResources(Length + IncreaseSize);
|
||||
|
||||
var control = (Info*)(Data + 4);
|
||||
var entries = (ushort*)(control + Count);
|
||||
var entries = (EstEntry*)(control + Count);
|
||||
|
||||
for (var i = Count - 1; i >= idx; --i)
|
||||
entries[i + 3] = entries[i];
|
||||
|
|
@ -94,10 +94,10 @@ public sealed unsafe class EstFile : MetaBaseFile
|
|||
[StructLayout(LayoutKind.Sequential, Size = 4)]
|
||||
private struct Info : IComparable<Info>
|
||||
{
|
||||
public readonly ushort SetId;
|
||||
public readonly PrimaryId SetId;
|
||||
public readonly GenderRace GenderRace;
|
||||
|
||||
public Info(GenderRace gr, ushort setId)
|
||||
public Info(GenderRace gr, PrimaryId setId)
|
||||
{
|
||||
GenderRace = gr;
|
||||
SetId = setId;
|
||||
|
|
@ -106,42 +106,42 @@ public sealed unsafe class EstFile : MetaBaseFile
|
|||
public int CompareTo(Info other)
|
||||
{
|
||||
var genderRaceComparison = GenderRace.CompareTo(other.GenderRace);
|
||||
return genderRaceComparison != 0 ? genderRaceComparison : SetId.CompareTo(other.SetId);
|
||||
return genderRaceComparison != 0 ? genderRaceComparison : SetId.Id.CompareTo(other.SetId.Id);
|
||||
}
|
||||
}
|
||||
|
||||
private static (int, bool) FindEntry(ReadOnlySpan<Info> data, GenderRace genderRace, ushort setId)
|
||||
private static (int, bool) FindEntry(ReadOnlySpan<Info> data, GenderRace genderRace, PrimaryId setId)
|
||||
{
|
||||
var idx = data.BinarySearch(new Info(genderRace, setId));
|
||||
return idx < 0 ? (~idx, false) : (idx, true);
|
||||
}
|
||||
|
||||
private (int, bool) FindEntry(GenderRace genderRace, ushort setId)
|
||||
private (int, bool) FindEntry(GenderRace genderRace, PrimaryId setId)
|
||||
{
|
||||
var span = new ReadOnlySpan<Info>(Data + 4, Count);
|
||||
return FindEntry(span, genderRace, setId);
|
||||
}
|
||||
|
||||
public EstEntryChange SetEntry(GenderRace genderRace, ushort setId, ushort skeletonId)
|
||||
public EstEntryChange SetEntry(GenderRace genderRace, PrimaryId setId, EstEntry skeletonId)
|
||||
{
|
||||
var (idx, exists) = FindEntry(genderRace, setId);
|
||||
if (exists)
|
||||
{
|
||||
var value = *(ushort*)(Data + 4 * (Count + 1) + 2 * idx);
|
||||
var value = *(EstEntry*)(Data + 4 * (Count + 1) + 2 * idx);
|
||||
if (value == skeletonId)
|
||||
return EstEntryChange.Unchanged;
|
||||
|
||||
if (skeletonId == 0)
|
||||
if (skeletonId == EstEntry.Zero)
|
||||
{
|
||||
RemoveEntry(idx);
|
||||
return EstEntryChange.Removed;
|
||||
}
|
||||
|
||||
*(ushort*)(Data + 4 * (Count + 1) + 2 * idx) = skeletonId;
|
||||
*(EstEntry*)(Data + 4 * (Count + 1) + 2 * idx) = skeletonId;
|
||||
return EstEntryChange.Changed;
|
||||
}
|
||||
|
||||
if (skeletonId == 0)
|
||||
if (skeletonId == EstEntry.Zero)
|
||||
return EstEntryChange.Unchanged;
|
||||
|
||||
InsertEntry(idx, genderRace, setId, skeletonId);
|
||||
|
|
@ -156,7 +156,7 @@ public sealed unsafe class EstFile : MetaBaseFile
|
|||
MemoryUtility.MemSet(Data + length, 0, Length - length);
|
||||
}
|
||||
|
||||
public EstFile(MetaFileManager manager, EstManipulation.EstType estType)
|
||||
public EstFile(MetaFileManager manager, EstType estType)
|
||||
: base(manager, (MetaIndex)estType)
|
||||
{
|
||||
var length = DefaultData.Length;
|
||||
|
|
@ -164,24 +164,24 @@ public sealed unsafe class EstFile : MetaBaseFile
|
|||
Reset();
|
||||
}
|
||||
|
||||
public ushort GetDefault(GenderRace genderRace, ushort setId)
|
||||
public EstEntry GetDefault(GenderRace genderRace, PrimaryId setId)
|
||||
=> GetDefault(Manager, Index, genderRace, setId);
|
||||
|
||||
public static ushort GetDefault(MetaFileManager manager, CharacterUtility.InternalIndex index, GenderRace genderRace, PrimaryId primaryId)
|
||||
public static EstEntry GetDefault(MetaFileManager manager, CharacterUtility.InternalIndex index, GenderRace genderRace, PrimaryId primaryId)
|
||||
{
|
||||
var data = (byte*)manager.CharacterUtility.DefaultResource(index).Address;
|
||||
var count = *(int*)data;
|
||||
var span = new ReadOnlySpan<Info>(data + 4, count);
|
||||
var (idx, found) = FindEntry(span, genderRace, primaryId.Id);
|
||||
if (!found)
|
||||
return 0;
|
||||
return EstEntry.Zero;
|
||||
|
||||
return *(ushort*)(data + 4 + count * EntryDescSize + idx * EntrySize);
|
||||
return *(EstEntry*)(data + 4 + count * EntryDescSize + idx * EntrySize);
|
||||
}
|
||||
|
||||
public static ushort GetDefault(MetaFileManager manager, MetaIndex metaIndex, GenderRace genderRace, PrimaryId primaryId)
|
||||
public static EstEntry GetDefault(MetaFileManager manager, MetaIndex metaIndex, GenderRace genderRace, PrimaryId primaryId)
|
||||
=> GetDefault(manager, CharacterUtility.ReverseIndices[(int)metaIndex], genderRace, primaryId);
|
||||
|
||||
public static ushort GetDefault(MetaFileManager manager, EstManipulation.EstType estType, GenderRace genderRace, PrimaryId primaryId)
|
||||
public static EstEntry GetDefault(MetaFileManager manager, EstType estType, GenderRace genderRace, PrimaryId primaryId)
|
||||
=> GetDefault(manager, (MetaIndex)estType, genderRace, primaryId);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue