mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
RT: Use SpanTextWriter to assemble paths
This commit is contained in:
parent
4454ac48da
commit
c849e31034
2 changed files with 33 additions and 20 deletions
|
|
@ -1,5 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using OtterGui.Text.HelperObjects;
|
||||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -8,6 +9,7 @@ using Penumbra.Meta.Manipulations;
|
|||
using Penumbra.String;
|
||||
using Penumbra.String.Classes;
|
||||
using static Penumbra.Interop.Structs.StructExtensions;
|
||||
using CharaBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase;
|
||||
using ModelType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase.ModelType;
|
||||
|
||||
namespace Penumbra.Interop.ResourceTree;
|
||||
|
|
@ -95,7 +97,7 @@ internal partial record ResolveContext
|
|||
var variant = ResolveMaterialVariant(imc, Equipment.Variant);
|
||||
var fileName = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(mtrlFileName);
|
||||
|
||||
Span<byte> pathBuffer = stackalloc byte[260];
|
||||
Span<byte> pathBuffer = stackalloc byte[CharaBase.PathBufferSize];
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, fileName);
|
||||
|
||||
return Utf8GamePath.FromSpan(pathBuffer, MetaDataComputation.None, out var path) ? path.Clone() : Utf8GamePath.Empty;
|
||||
|
|
@ -125,7 +127,7 @@ internal partial record ResolveContext
|
|||
fileName.CopyTo(mirroredFileName);
|
||||
WriteZeroPaddedNumber(mirroredFileName[4..8], mirroredSetId);
|
||||
|
||||
Span<byte> pathBuffer = stackalloc byte[260];
|
||||
Span<byte> pathBuffer = stackalloc byte[CharaBase.PathBufferSize];
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, mirroredFileName);
|
||||
|
||||
var weaponPosition = pathBuffer.IndexOf("/weapon/w"u8);
|
||||
|
|
@ -144,7 +146,7 @@ internal partial record ResolveContext
|
|||
var variant = ResolveMaterialVariant(imc, (byte)((Monster*)CharacterBase)->Variant);
|
||||
var fileName = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(mtrlFileName);
|
||||
|
||||
Span<byte> pathBuffer = stackalloc byte[260];
|
||||
Span<byte> pathBuffer = stackalloc byte[CharaBase.PathBufferSize];
|
||||
pathBuffer = AssembleMaterialPath(pathBuffer, modelPath.Path.Span, variant, fileName);
|
||||
|
||||
return Utf8GamePath.FromSpan(pathBuffer, MetaDataComputation.None, out var path) ? path.Clone() : Utf8GamePath.Empty;
|
||||
|
|
@ -175,13 +177,21 @@ internal partial record ResolveContext
|
|||
|
||||
var baseDirectory = modelPath[..modelPosition];
|
||||
|
||||
baseDirectory.CopyTo(materialPathBuffer);
|
||||
"/material/v"u8.CopyTo(materialPathBuffer[baseDirectory.Length..]);
|
||||
WriteZeroPaddedNumber(materialPathBuffer.Slice(baseDirectory.Length + 11, 4), variant);
|
||||
materialPathBuffer[baseDirectory.Length + 15] = (byte)'/';
|
||||
mtrlFileName.CopyTo(materialPathBuffer[(baseDirectory.Length + 16)..]);
|
||||
var writer = new SpanTextWriter(materialPathBuffer);
|
||||
writer.Append(baseDirectory);
|
||||
writer.Append("/material/v"u8);
|
||||
WriteZeroPaddedNumber(ref writer, 4, variant);
|
||||
writer.Append((byte)'/');
|
||||
writer.Append(mtrlFileName);
|
||||
writer.EnsureNullTerminated();
|
||||
|
||||
return materialPathBuffer[..(baseDirectory.Length + 16 + mtrlFileName.Length)];
|
||||
return materialPathBuffer[..writer.Position];
|
||||
}
|
||||
|
||||
private static void WriteZeroPaddedNumber(ref SpanTextWriter writer, int width, ushort number)
|
||||
{
|
||||
WriteZeroPaddedNumber(writer.GetRemainingSpan()[..width], number);
|
||||
writer.Advance(width);
|
||||
}
|
||||
|
||||
private static void WriteZeroPaddedNumber(Span<byte> destination, ushort number)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using FFXIVClientStructs.Interop;
|
||||
using OtterGui;
|
||||
using OtterGui.Text.HelperObjects;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Data;
|
||||
|
|
@ -16,7 +16,7 @@ using Penumbra.String;
|
|||
using Penumbra.String.Classes;
|
||||
using Penumbra.UI;
|
||||
using static Penumbra.Interop.Structs.StructExtensions;
|
||||
using ModelType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase.ModelType;
|
||||
using CharaBase = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase;
|
||||
|
||||
namespace Penumbra.Interop.ResourceTree;
|
||||
|
||||
|
|
@ -29,25 +29,25 @@ internal record GlobalResolveContext(
|
|||
{
|
||||
public readonly Dictionary<(Utf8GamePath, nint), ResourceNode> Nodes = new(128);
|
||||
|
||||
public unsafe ResolveContext CreateContext(CharacterBase* characterBase, uint slotIndex = 0xFFFFFFFFu,
|
||||
public unsafe ResolveContext CreateContext(CharaBase* characterBase, uint slotIndex = 0xFFFFFFFFu,
|
||||
EquipSlot slot = EquipSlot.Unknown, CharacterArmor equipment = default, SecondaryId secondaryId = default)
|
||||
=> new(this, characterBase, slotIndex, slot, equipment, secondaryId);
|
||||
}
|
||||
|
||||
internal unsafe partial record ResolveContext(
|
||||
GlobalResolveContext Global,
|
||||
Pointer<CharacterBase> CharacterBasePointer,
|
||||
Pointer<CharaBase> CharacterBasePointer,
|
||||
uint SlotIndex,
|
||||
EquipSlot Slot,
|
||||
CharacterArmor Equipment,
|
||||
SecondaryId SecondaryId)
|
||||
{
|
||||
public CharacterBase* CharacterBase
|
||||
public CharaBase* CharacterBase
|
||||
=> CharacterBasePointer.Value;
|
||||
|
||||
private static readonly CiByteString ShpkPrefix = CiByteString.FromSpanUnsafe("shader/sm5/shpk"u8, true, true, true);
|
||||
|
||||
private ModelType ModelType
|
||||
private CharaBase.ModelType ModelType
|
||||
=> CharacterBase->GetModelType();
|
||||
|
||||
private ResourceNode? CreateNodeFromShpk(ShaderPackageResourceHandle* resourceHandle, CiByteString gamePath)
|
||||
|
|
@ -75,11 +75,14 @@ internal unsafe partial record ResolveContext(
|
|||
if (lastDirectorySeparator == -1 || lastDirectorySeparator > gamePath.Length - 3)
|
||||
return null;
|
||||
|
||||
Span<byte> prefixed = stackalloc byte[260];
|
||||
gamePath.Span[..(lastDirectorySeparator + 1)].CopyTo(prefixed);
|
||||
prefixed[lastDirectorySeparator + 1] = (byte)'-';
|
||||
prefixed[lastDirectorySeparator + 2] = (byte)'-';
|
||||
gamePath.Span[(lastDirectorySeparator + 1)..].CopyTo(prefixed[(lastDirectorySeparator + 3)..]);
|
||||
Span<byte> prefixed = stackalloc byte[CharaBase.PathBufferSize];
|
||||
|
||||
var writer = new SpanTextWriter(prefixed);
|
||||
writer.Append(gamePath.Span[..(lastDirectorySeparator + 1)]);
|
||||
writer.Append((byte)'-');
|
||||
writer.Append((byte)'-');
|
||||
writer.Append(gamePath.Span[(lastDirectorySeparator + 1)..]);
|
||||
writer.EnsureNullTerminated();
|
||||
|
||||
if (!Utf8GamePath.FromSpan(prefixed[..(gamePath.Length + 2)], MetaDataComputation.None, out var tmp))
|
||||
return null;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue