mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-20 23:07:51 +01:00
Make line endings explicit in editorconfig and share in sub projects, also apply editorconfig everywhere and move some namespaces.
This commit is contained in:
parent
53adb6fa54
commit
2b4a01df06
155 changed files with 1620 additions and 1614 deletions
|
|
@ -80,7 +80,8 @@ public sealed unsafe class LiveColorTablePreviewer : LiveMaterialPreviewerBase
|
|||
textureSize[0] = TextureWidth;
|
||||
textureSize[1] = TextureHeight;
|
||||
|
||||
using var texture = new SafeTextureHandle(Structs.TextureUtility.Create2D(Device.Instance(), textureSize, 1, 0x2460, 0x80000804, 7), false);
|
||||
using var texture =
|
||||
new SafeTextureHandle(Structs.TextureUtility.Create2D(Device.Instance(), textureSize, 1, 0x2460, 0x80000804, 7), false);
|
||||
if (texture.IsInvalid)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Penumbra.Interop.PathResolving;
|
|||
public unsafe class AnimationHookService : IDisposable
|
||||
{
|
||||
private readonly PerformanceTracker _performance;
|
||||
private readonly IObjectTable _objects;
|
||||
private readonly IObjectTable _objects;
|
||||
private readonly CollectionResolver _collectionResolver;
|
||||
private readonly DrawObjectState _drawObjectState;
|
||||
private readonly CollectionResolver _resolver;
|
||||
|
|
@ -34,7 +34,7 @@ public unsafe class AnimationHookService : IDisposable
|
|||
_collectionResolver = collectionResolver;
|
||||
_drawObjectState = drawObjectState;
|
||||
_resolver = resolver;
|
||||
_conditions = conditions;
|
||||
_conditions = conditions;
|
||||
|
||||
SignatureHelper.Initialise(this);
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ public unsafe class AnimationHookService : IDisposable
|
|||
var last = _characterSoundData.Value;
|
||||
_characterSoundData.Value = _collectionResolver.IdentifyCollection((GameObject*)character, true);
|
||||
var ret = _loadCharacterSoundHook.Original(character, unk1, unk2, unk3, unk4, unk5, unk6, unk7);
|
||||
_characterSoundData.Value = last;
|
||||
_characterSoundData.Value = last;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -140,15 +140,15 @@ public unsafe class AnimationHookService : IDisposable
|
|||
using var performance = _performance.Measure(PerformanceType.TimelineResources);
|
||||
// Do not check timeline loading in cutscenes.
|
||||
if (_conditions[ConditionFlag.OccupiedInCutSceneEvent] || _conditions[ConditionFlag.WatchingCutscene78])
|
||||
return _loadTimelineResourcesHook.Original(timeline);
|
||||
return _loadTimelineResourcesHook.Original(timeline);
|
||||
|
||||
var last = _animationLoadData.Value;
|
||||
var last = _animationLoadData.Value;
|
||||
_animationLoadData.Value = GetDataFromTimeline(timeline);
|
||||
var ret = _loadTimelineResourcesHook.Original(timeline);
|
||||
_animationLoadData.Value = last;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Probably used when the base idle animation gets loaded.
|
||||
/// Make it aware of the correct collection to load the correct pap files.
|
||||
|
|
@ -297,12 +297,12 @@ public unsafe class AnimationHookService : IDisposable
|
|||
try
|
||||
{
|
||||
if (timeline != IntPtr.Zero)
|
||||
{
|
||||
{
|
||||
var getGameObjectIdx = ((delegate* unmanaged<nint, int>**)timeline)[0][Offsets.GetGameObjectIdxVfunc];
|
||||
var idx = getGameObjectIdx(timeline);
|
||||
if (idx >= 0 && idx < _objects.Length)
|
||||
{
|
||||
var obj = (GameObject*)_objects.GetObjectAddress(idx);
|
||||
var obj = (GameObject*)_objects.GetObjectAddress(idx);
|
||||
return obj != null ? _collectionResolver.IdentifyCollection(obj, true) : ResolveData.Invalid;
|
||||
}
|
||||
}
|
||||
|
|
@ -378,17 +378,17 @@ public unsafe class AnimationHookService : IDisposable
|
|||
if (a6 == nint.Zero)
|
||||
return _apricotListenerSoundPlayHook!.Original(a1, a2, a3, a4, a5, a6);
|
||||
|
||||
var last = _animationLoadData.Value;
|
||||
// a6 is some instance of Apricot.IInstanceListenner, in some cases we can obtain the associated caster via vfunc 1.
|
||||
var last = _animationLoadData.Value;
|
||||
// a6 is some instance of Apricot.IInstanceListenner, in some cases we can obtain the associated caster via vfunc 1.
|
||||
var gameObject = (*(delegate* unmanaged<nint, GameObject*>**)a6)[1](a6);
|
||||
if (gameObject != null)
|
||||
{
|
||||
_animationLoadData.Value = _collectionResolver.IdentifyCollection(gameObject, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// for VfxListenner we can obtain the associated draw object as its first member,
|
||||
// if the object has different type, drawObject will contain other values or garbage,
|
||||
{
|
||||
// for VfxListenner we can obtain the associated draw object as its first member,
|
||||
// if the object has different type, drawObject will contain other values or garbage,
|
||||
// but only be used in a dictionary pointer lookup, so this does not hurt.
|
||||
var drawObject = ((DrawObject**)a6)[1];
|
||||
if (drawObject != null)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public unsafe class CollectionResolver
|
|||
private readonly HumanModelList _humanModels;
|
||||
|
||||
private readonly IClientState _clientState;
|
||||
private readonly IGameGui _gameGui;
|
||||
private readonly IGameGui _gameGui;
|
||||
private readonly ActorService _actors;
|
||||
private readonly CutsceneService _cutscenes;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Penumbra.Interop.PathResolving;
|
|||
|
||||
public class DrawObjectState : IDisposable, IReadOnlyDictionary<nint, (nint, bool)>
|
||||
{
|
||||
private readonly IObjectTable _objects;
|
||||
private readonly IObjectTable _objects;
|
||||
private readonly GameEventManager _gameEvents;
|
||||
|
||||
private readonly Dictionary<nint, (nint GameObject, bool IsChild)> _drawObjectToGameObject = new();
|
||||
|
|
@ -71,8 +71,8 @@ public class DrawObjectState : IDisposable, IReadOnlyDictionary<nint, (nint, boo
|
|||
|
||||
private unsafe void OnWeaponReloaded(nint _, nint gameObject)
|
||||
{
|
||||
_lastGameObject.Value!.Dequeue();
|
||||
IterateDrawObjectTree((Object*) ((GameObject*) gameObject)->DrawObject, gameObject, false, false);
|
||||
_lastGameObject.Value!.Dequeue();
|
||||
IterateDrawObjectTree((Object*)((GameObject*)gameObject)->DrawObject, gameObject, false, false);
|
||||
}
|
||||
|
||||
private void OnCharacterBaseDestructor(nint characterBase)
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(nint A
|
|||
_events = events;
|
||||
|
||||
_communicator.CollectionChange.Subscribe(CollectionChangeClear, CollectionChange.Priority.IdentifiedCollectionCache);
|
||||
_clientState.TerritoryChanged += TerritoryClear;
|
||||
_events.CharacterDestructor += OnCharacterDestruct;
|
||||
_clientState.TerritoryChanged += TerritoryClear;
|
||||
_events.CharacterDestructor += OnCharacterDestruct;
|
||||
}
|
||||
|
||||
public ResolveData Set(ModCollection collection, ActorIdentifier identifier, GameObject* data)
|
||||
|
|
@ -61,8 +61,8 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable<(nint A
|
|||
public void Dispose()
|
||||
{
|
||||
_communicator.CollectionChange.Unsubscribe(CollectionChangeClear);
|
||||
_clientState.TerritoryChanged -= TerritoryClear;
|
||||
_events.CharacterDestructor -= OnCharacterDestruct;
|
||||
_clientState.TerritoryChanged -= TerritoryClear;
|
||||
_events.CharacterDestructor -= OnCharacterDestruct;
|
||||
}
|
||||
|
||||
public IEnumerator<(nint Address, ActorIdentifier Identifier, ModCollection Collection)> GetEnumerator()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System.Collections.Concurrent;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using Penumbra.Collections;
|
||||
|
|
|
|||
|
|
@ -81,6 +81,6 @@ public unsafe class FileReadService : IDisposable
|
|||
/// </summary>
|
||||
private nint GetResourceManager()
|
||||
=> !_lastFileThreadResourceManager.IsValueCreated || _lastFileThreadResourceManager.Value == IntPtr.Zero
|
||||
? (nint) _resourceManager.ResourceManager
|
||||
? (nint)_resourceManager.ResourceManager
|
||||
: _lastFileThreadResourceManager.Value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ public class ResourceNode
|
|||
Children = new List<ResourceNode>();
|
||||
}
|
||||
|
||||
public ResourceNode(UIData uiData, ResourceType type, nint objectAddress, nint resourceHandle, Utf8GamePath[] possibleGamePaths, FullPath fullPath,
|
||||
public ResourceNode(UIData uiData, ResourceType type, nint objectAddress, nint resourceHandle, Utf8GamePath[] possibleGamePaths,
|
||||
FullPath fullPath,
|
||||
ulong length, bool @internal)
|
||||
{
|
||||
Name = uiData.Name;
|
||||
|
|
@ -69,7 +70,7 @@ public class ResourceNode
|
|||
}
|
||||
|
||||
public ResourceNode WithUIData(string? name, ChangedItemIcon icon)
|
||||
=> string.Equals(Name, name, StringComparison.Ordinal) && Icon == icon ? this : new ResourceNode(new(name, icon), this);
|
||||
=> string.Equals(Name, name, StringComparison.Ordinal) && Icon == icon ? this : new ResourceNode(new UIData(name, icon), this);
|
||||
|
||||
public ResourceNode WithUIData(UIData uiData)
|
||||
=> string.Equals(Name, uiData.Name, StringComparison.Ordinal) && Icon == uiData.Icon ? this : new ResourceNode(uiData, this);
|
||||
|
|
@ -77,6 +78,6 @@ public class ResourceNode
|
|||
public readonly record struct UIData(string? Name, ChangedItemIcon Icon)
|
||||
{
|
||||
public readonly UIData PrependName(string prefix)
|
||||
=> Name == null ? this : new(prefix + Name, Icon);
|
||||
=> Name == null ? this : new UIData(prefix + Name, Icon);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
|
|
@ -16,7 +16,7 @@ public class ResourceTree
|
|||
public readonly nint DrawObjectAddress;
|
||||
public readonly bool PlayerRelated;
|
||||
public readonly string CollectionName;
|
||||
public readonly List<ResourceNode> Nodes;
|
||||
public readonly List<ResourceNode> Nodes;
|
||||
public readonly HashSet<ResourceNode> FlatNodes;
|
||||
|
||||
public int ModelId;
|
||||
|
|
@ -26,11 +26,11 @@ public class ResourceTree
|
|||
public ResourceTree(string name, nint gameObjectAddress, nint drawObjectAddress, bool playerRelated, string collectionName)
|
||||
{
|
||||
Name = name;
|
||||
GameObjectAddress = gameObjectAddress;
|
||||
GameObjectAddress = gameObjectAddress;
|
||||
DrawObjectAddress = drawObjectAddress;
|
||||
PlayerRelated = playerRelated;
|
||||
CollectionName = collectionName;
|
||||
Nodes = new List<ResourceNode>();
|
||||
Nodes = new List<ResourceNode>();
|
||||
FlatNodes = new HashSet<ResourceNode>();
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ public class ResourceTree
|
|||
// var customize = new ReadOnlySpan<byte>( character->CustomizeData, 26 );
|
||||
ModelId = character->CharacterData.ModelCharaId;
|
||||
CustomizeData = character->DrawData.CustomizeData;
|
||||
RaceCode = model->GetModelType() == CharacterBase.ModelType.Human ? (GenderRace) ((Human*)model)->RaceSexId : GenderRace.Unknown;
|
||||
RaceCode = model->GetModelType() == CharacterBase.ModelType.Human ? (GenderRace)((Human*)model)->RaceSexId : GenderRace.Unknown;
|
||||
|
||||
for (var i = 0; i < model->SlotCount; ++i)
|
||||
{
|
||||
|
|
@ -60,8 +60,8 @@ public class ResourceTree
|
|||
var mdlNode = context.CreateNodeFromRenderModel(mdl);
|
||||
if (mdlNode != null)
|
||||
Nodes.Add(globalContext.WithUiData ? mdlNode.WithUIData(mdlNode.Name ?? $"Model #{i}", mdlNode.Icon) : mdlNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AddSkeleton(Nodes, globalContext.CreateContext(EquipSlot.Unknown, default), model->Skeleton);
|
||||
|
||||
if (character->GameObject.GetObjectKind() == (byte)ObjectKind.Pc)
|
||||
|
|
@ -100,8 +100,8 @@ public class ResourceTree
|
|||
subObjectNodes.Add(globalContext.WithUiData
|
||||
? mdlNode.WithUIData(mdlNode.Name ?? $"{subObjectNamePrefix} #{subObjectIndex}, Model #{i}", mdlNode.Icon)
|
||||
: mdlNode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
AddSkeleton(subObjectNodes, subObjectContext, subObject->Skeleton, $"{subObjectNamePrefix} #{subObjectIndex}, ");
|
||||
|
||||
subObject = (CharacterBase*)subObject->DrawObject.Object.NextSiblingObject;
|
||||
|
|
@ -119,19 +119,21 @@ public class ResourceTree
|
|||
|
||||
var legacyDecalNode = context.CreateNodeFromTex((TextureResourceHandle*)human->LegacyBodyDecal);
|
||||
if (legacyDecalNode != null)
|
||||
Nodes.Add(globalContext.WithUiData ? legacyDecalNode.WithUIData(legacyDecalNode.Name ?? "Legacy Body Decal", legacyDecalNode.Icon) : legacyDecalNode);
|
||||
}
|
||||
|
||||
private unsafe void AddSkeleton(List<ResourceNode> nodes, ResolveContext context, Skeleton* skeleton, string prefix = "")
|
||||
{
|
||||
if (skeleton == null)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < skeleton->PartialSkeletonCount; ++i)
|
||||
{
|
||||
var sklbNode = context.CreateNodeFromPartialSkeleton(&skeleton->PartialSkeletons[i]);
|
||||
if (sklbNode != null)
|
||||
nodes.Add(context.WithUiData ? sklbNode.WithUIData($"{prefix}Skeleton #{i}", sklbNode.Icon) : sklbNode);
|
||||
}
|
||||
Nodes.Add(globalContext.WithUiData
|
||||
? legacyDecalNode.WithUIData(legacyDecalNode.Name ?? "Legacy Body Decal", legacyDecalNode.Icon)
|
||||
: legacyDecalNode);
|
||||
}
|
||||
|
||||
private unsafe void AddSkeleton(List<ResourceNode> nodes, ResolveContext context, Skeleton* skeleton, string prefix = "")
|
||||
{
|
||||
if (skeleton == null)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < skeleton->PartialSkeletonCount; ++i)
|
||||
{
|
||||
var sklbNode = context.CreateNodeFromPartialSkeleton(&skeleton->PartialSkeletons[i]);
|
||||
if (sklbNode != null)
|
||||
nodes.Add(context.WithUiData ? sklbNode.WithUIData($"{prefix}Skeleton #{i}", sklbNode.Icon) : sklbNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,21 +4,25 @@ namespace Penumbra.Interop.SafeHandles;
|
|||
|
||||
public unsafe class SafeResourceHandle : SafeHandle
|
||||
{
|
||||
public ResourceHandle* ResourceHandle => (ResourceHandle*)handle;
|
||||
public ResourceHandle* ResourceHandle
|
||||
=> (ResourceHandle*)handle;
|
||||
|
||||
public override bool IsInvalid => handle == 0;
|
||||
public override bool IsInvalid
|
||||
=> handle == 0;
|
||||
|
||||
public SafeResourceHandle(ResourceHandle* handle, bool incRef, bool ownsHandle = true) : base(0, ownsHandle)
|
||||
public SafeResourceHandle(ResourceHandle* handle, bool incRef, bool ownsHandle = true)
|
||||
: base(0, ownsHandle)
|
||||
{
|
||||
if (incRef && !ownsHandle)
|
||||
throw new ArgumentException("Non-owning SafeResourceHandle with IncRef is unsupported");
|
||||
|
||||
if (incRef && handle != null)
|
||||
handle->IncRef();
|
||||
SetHandle((nint)handle);
|
||||
}
|
||||
|
||||
public static SafeResourceHandle CreateInvalid()
|
||||
=> new(null, incRef: false);
|
||||
=> new(null, false);
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,14 +5,18 @@ namespace Penumbra.Interop.SafeHandles;
|
|||
|
||||
public unsafe class SafeTextureHandle : SafeHandle
|
||||
{
|
||||
public Texture* Texture => (Texture*)handle;
|
||||
public Texture* Texture
|
||||
=> (Texture*)handle;
|
||||
|
||||
public override bool IsInvalid => handle == 0;
|
||||
public override bool IsInvalid
|
||||
=> handle == 0;
|
||||
|
||||
public SafeTextureHandle(Texture* handle, bool incRef, bool ownsHandle = true) : base(0, ownsHandle)
|
||||
public SafeTextureHandle(Texture* handle, bool incRef, bool ownsHandle = true)
|
||||
: base(0, ownsHandle)
|
||||
{
|
||||
if (incRef && !ownsHandle)
|
||||
throw new ArgumentException("Non-owning SafeTextureHandle with IncRef is unsupported");
|
||||
|
||||
if (incRef && handle != null)
|
||||
TextureUtility.IncRef(handle);
|
||||
SetHandle((nint)handle);
|
||||
|
|
@ -27,16 +31,17 @@ public unsafe class SafeTextureHandle : SafeHandle
|
|||
}
|
||||
|
||||
public static SafeTextureHandle CreateInvalid()
|
||||
=> new(null, incRef: false);
|
||||
=> new(null, false);
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
nint handle;
|
||||
lock (this)
|
||||
{
|
||||
handle = this.handle;
|
||||
handle = this.handle;
|
||||
this.handle = 0;
|
||||
}
|
||||
|
||||
if (handle != 0)
|
||||
TextureUtility.DecRef((Texture*)handle);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public sealed unsafe class DecalReverter : IDisposable
|
|||
public static readonly Utf8GamePath TransparentPath =
|
||||
Utf8GamePath.FromSpan("chara/common/texture/transparent.tex"u8, out var p) ? p : Utf8GamePath.Empty;
|
||||
|
||||
private readonly CharacterUtility _utility;
|
||||
private readonly CharacterUtility _utility;
|
||||
private readonly Structs.TextureResourceHandle* _decal;
|
||||
private readonly Structs.TextureResourceHandle* _transparent;
|
||||
|
||||
|
|
@ -22,10 +22,10 @@ public sealed unsafe class DecalReverter : IDisposable
|
|||
{
|
||||
_utility = utility;
|
||||
var ptr = _utility.Address;
|
||||
_decal = null;
|
||||
_decal = null;
|
||||
_transparent = null;
|
||||
if (!config.EnableMods)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (doDecal)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public unsafe class GameEventManager : IDisposable
|
|||
{
|
||||
try
|
||||
{
|
||||
((CreatingCharacterBaseEvent)subscriber).Invoke((nint) (&a), b, c);
|
||||
((CreatingCharacterBaseEvent)subscriber).Invoke((nint)(&a), b, c);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -265,11 +265,13 @@ public unsafe class GameEventManager : IDisposable
|
|||
private readonly Hook<TestDelegate>? _testHook = null;
|
||||
|
||||
private delegate void TestDelegate(nint a1, int a2);
|
||||
|
||||
private void TestDetour(nint a1, int a2)
|
||||
{
|
||||
Penumbra.Log.Information($"Test: {a1:X} {a2}");
|
||||
_testHook!.Original(a1, a2);
|
||||
}
|
||||
|
||||
private void EnableDebugHook()
|
||||
=> _testHook?.Enable();
|
||||
|
||||
|
|
|
|||
|
|
@ -100,10 +100,10 @@ public unsafe partial class RedrawService
|
|||
|
||||
public sealed unsafe partial class RedrawService : IDisposable
|
||||
{
|
||||
private readonly Framework _framework;
|
||||
private readonly Framework _framework;
|
||||
private readonly IObjectTable _objects;
|
||||
private readonly ITargetManager _targets;
|
||||
private readonly Condition _conditions;
|
||||
private readonly Condition _conditions;
|
||||
|
||||
private readonly List<int> _queue = new(100);
|
||||
private readonly List<int> _afterGPoseQueue = new(GPoseSlots);
|
||||
|
|
@ -207,7 +207,7 @@ public sealed unsafe partial class RedrawService : IDisposable
|
|||
return;
|
||||
|
||||
_targets.Target = actor;
|
||||
_target = -1;
|
||||
_target = -1;
|
||||
}
|
||||
|
||||
private void HandleRedraw()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Dalamud.Utility.Signatures;
|
||||
using Penumbra.GameData;
|
||||
|
||||
|
||||
namespace Penumbra.Interop.Services;
|
||||
|
||||
public unsafe class ResidentResourceManager
|
||||
|
|
@ -36,4 +36,4 @@ public unsafe class ResidentResourceManager
|
|||
LoadPlayerResources.Invoke(Address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,23 @@ using Penumbra.GameData.Enums;
|
|||
|
||||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct CharacterUtilityData
|
||||
{
|
||||
public const int IndexTransparentTex = 72;
|
||||
public const int IndexDecalTex = 73;
|
||||
public const int IndexSkinShpk = 76;
|
||||
|
||||
public static readonly MetaIndex[] EqdpIndices = Enum.GetNames< MetaIndex >()
|
||||
.Zip( Enum.GetValues< MetaIndex >() )
|
||||
.Where( n => n.First.StartsWith( "Eqdp" ) )
|
||||
.Select( n => n.Second ).ToArray();
|
||||
public static readonly MetaIndex[] EqdpIndices = Enum.GetNames<MetaIndex>()
|
||||
.Zip(Enum.GetValues<MetaIndex>())
|
||||
.Where(n => n.First.StartsWith("Eqdp"))
|
||||
.Select(n => n.Second).ToArray();
|
||||
|
||||
public const int TotalNumResources = 87;
|
||||
|
||||
/// <summary> Obtain the index for the eqdp file corresponding to the given race code and accessory. </summary>
|
||||
public static MetaIndex EqdpIdx( GenderRace raceCode, bool accessory )
|
||||
=> +( int )raceCode switch
|
||||
public static MetaIndex EqdpIdx(GenderRace raceCode, bool accessory)
|
||||
=> +(int)raceCode switch
|
||||
{
|
||||
0101 => accessory ? MetaIndex.Eqdp0101Acc : MetaIndex.Eqdp0101,
|
||||
0201 => accessory ? MetaIndex.Eqdp0201Acc : MetaIndex.Eqdp0201,
|
||||
|
|
@ -48,53 +48,53 @@ public unsafe struct CharacterUtilityData
|
|||
1404 => accessory ? MetaIndex.Eqdp1404Acc : MetaIndex.Eqdp1404,
|
||||
9104 => accessory ? MetaIndex.Eqdp9104Acc : MetaIndex.Eqdp9104,
|
||||
9204 => accessory ? MetaIndex.Eqdp9204Acc : MetaIndex.Eqdp9204,
|
||||
_ => ( MetaIndex )( -1 ),
|
||||
_ => (MetaIndex)(-1),
|
||||
};
|
||||
|
||||
[FieldOffset( 0 )]
|
||||
[FieldOffset(0)]
|
||||
public void* VTable;
|
||||
|
||||
[FieldOffset( 8 )]
|
||||
[FieldOffset(8)]
|
||||
public fixed ulong Resources[TotalNumResources];
|
||||
|
||||
[FieldOffset( 8 + ( int )MetaIndex.Eqp * 8 )]
|
||||
[FieldOffset(8 + (int)MetaIndex.Eqp * 8)]
|
||||
public ResourceHandle* EqpResource;
|
||||
|
||||
[FieldOffset( 8 + ( int )MetaIndex.Gmp * 8 )]
|
||||
[FieldOffset(8 + (int)MetaIndex.Gmp * 8)]
|
||||
public ResourceHandle* GmpResource;
|
||||
|
||||
public ResourceHandle* Resource( int idx )
|
||||
=> ( ResourceHandle* )Resources[ idx ];
|
||||
public ResourceHandle* Resource(int idx)
|
||||
=> (ResourceHandle*)Resources[idx];
|
||||
|
||||
public ResourceHandle* Resource( MetaIndex idx )
|
||||
=> Resource( ( int )idx );
|
||||
public ResourceHandle* Resource(MetaIndex idx)
|
||||
=> Resource((int)idx);
|
||||
|
||||
public ResourceHandle* EqdpResource( GenderRace raceCode, bool accessory )
|
||||
=> Resource( ( int )EqdpIdx( raceCode, accessory ) );
|
||||
public ResourceHandle* EqdpResource(GenderRace raceCode, bool accessory)
|
||||
=> Resource((int)EqdpIdx(raceCode, accessory));
|
||||
|
||||
[FieldOffset( 8 + ( int )MetaIndex.HumanCmp * 8 )]
|
||||
[FieldOffset(8 + (int)MetaIndex.HumanCmp * 8)]
|
||||
public ResourceHandle* HumanCmpResource;
|
||||
|
||||
[FieldOffset( 8 + ( int )MetaIndex.FaceEst * 8 )]
|
||||
[FieldOffset(8 + (int)MetaIndex.FaceEst * 8)]
|
||||
public ResourceHandle* FaceEstResource;
|
||||
|
||||
[FieldOffset( 8 + ( int )MetaIndex.HairEst * 8 )]
|
||||
[FieldOffset(8 + (int)MetaIndex.HairEst * 8)]
|
||||
public ResourceHandle* HairEstResource;
|
||||
|
||||
[FieldOffset( 8 + ( int )MetaIndex.BodyEst * 8 )]
|
||||
[FieldOffset(8 + (int)MetaIndex.BodyEst * 8)]
|
||||
public ResourceHandle* BodyEstResource;
|
||||
|
||||
[FieldOffset( 8 + ( int )MetaIndex.HeadEst * 8 )]
|
||||
[FieldOffset(8 + (int)MetaIndex.HeadEst * 8)]
|
||||
public ResourceHandle* HeadEstResource;
|
||||
|
||||
[FieldOffset( 8 + IndexTransparentTex * 8 )]
|
||||
[FieldOffset(8 + IndexTransparentTex * 8)]
|
||||
public TextureResourceHandle* TransparentTexResource;
|
||||
|
||||
[FieldOffset( 8 + IndexDecalTex * 8 )]
|
||||
[FieldOffset(8 + IndexDecalTex * 8)]
|
||||
public TextureResourceHandle* DecalTexResource;
|
||||
|
||||
[FieldOffset( 8 + IndexSkinShpk * 8 )]
|
||||
[FieldOffset(8 + IndexSkinShpk * 8)]
|
||||
public ResourceHandle* SkinShpkResource;
|
||||
|
||||
// not included resources have no known use case.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct ClipScheduler
|
||||
{
|
||||
[FieldOffset( 0 )]
|
||||
[FieldOffset(0)]
|
||||
public IntPtr* VTable;
|
||||
|
||||
[FieldOffset( 0x38 )]
|
||||
[FieldOffset(0x38)]
|
||||
public IntPtr SchedulerTimeline;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@ public enum DrawState : uint
|
|||
MaybeCulled = 0x00_00_04_00,
|
||||
MaybeHiddenMinion = 0x00_00_80_00,
|
||||
MaybeHiddenSummon = 0x00_80_00_00,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ public enum FileMode : byte
|
|||
// Probably debug options only.
|
||||
LoadIndexResource = 0xA, // load index/index2
|
||||
LoadSqPackResource = 0xB,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
|||
|
||||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct HumanExt
|
||||
{
|
||||
[FieldOffset( 0x0 )]
|
||||
[FieldOffset(0x0)]
|
||||
public Human Human;
|
||||
|
||||
[FieldOffset( 0x0 )]
|
||||
[FieldOffset(0x0)]
|
||||
public CharacterBaseExt CharacterBase;
|
||||
|
||||
[FieldOffset( 0x9E8 )]
|
||||
[FieldOffset(0x9E8)]
|
||||
public ResourceHandle* Decal;
|
||||
|
||||
[FieldOffset( 0x9F0 )]
|
||||
[FieldOffset(0x9F0)]
|
||||
public ResourceHandle* LegacyBodyDecal;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,45 +2,46 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
|||
|
||||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit, Size = 0x40 )]
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x40)]
|
||||
public unsafe struct Material
|
||||
{
|
||||
[FieldOffset( 0x10 )]
|
||||
[FieldOffset(0x10)]
|
||||
public MtrlResource* ResourceHandle;
|
||||
|
||||
[FieldOffset( 0x18 )]
|
||||
[FieldOffset(0x18)]
|
||||
public uint ShaderPackageFlags;
|
||||
|
||||
[FieldOffset( 0x20 )]
|
||||
[FieldOffset(0x20)]
|
||||
public uint* ShaderKeys;
|
||||
|
||||
public int ShaderKeyCount
|
||||
=> (int)((uint*)Textures - ShaderKeys);
|
||||
|
||||
[FieldOffset( 0x28 )]
|
||||
[FieldOffset(0x28)]
|
||||
public ConstantBuffer* MaterialParameter;
|
||||
|
||||
[FieldOffset( 0x30 )]
|
||||
[FieldOffset(0x30)]
|
||||
public TextureEntry* Textures;
|
||||
|
||||
[FieldOffset( 0x38 )]
|
||||
[FieldOffset(0x38)]
|
||||
public ushort TextureCount;
|
||||
|
||||
public Texture* Texture( int index ) => Textures[index].ResourceHandle->KernelTexture;
|
||||
public Texture* Texture(int index)
|
||||
=> Textures[index].ResourceHandle->KernelTexture;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit, Size = 0x18 )]
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x18)]
|
||||
public struct TextureEntry
|
||||
{
|
||||
[FieldOffset( 0x00 )]
|
||||
[FieldOffset(0x00)]
|
||||
public uint Id;
|
||||
|
||||
[FieldOffset( 0x08 )]
|
||||
[FieldOffset(0x08)]
|
||||
public TextureResourceHandle* ResourceHandle;
|
||||
|
||||
[FieldOffset( 0x10 )]
|
||||
[FieldOffset(0x10)]
|
||||
public uint SamplerFlags;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<TextureEntry> TextureSpan
|
||||
=> new(Textures, TextureCount);
|
||||
}
|
||||
=> new(Textures, TextureCount);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,45 +1,45 @@
|
|||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct MtrlResource
|
||||
{
|
||||
[FieldOffset( 0x00 )]
|
||||
[FieldOffset(0x00)]
|
||||
public ResourceHandle Handle;
|
||||
|
||||
[FieldOffset( 0xC8 )]
|
||||
[FieldOffset(0xC8)]
|
||||
public ShaderPackageResourceHandle* ShpkResourceHandle;
|
||||
|
||||
[FieldOffset( 0xD0 )]
|
||||
[FieldOffset(0xD0)]
|
||||
public TextureEntry* TexSpace; // Contains the offsets for the tex files inside the string list.
|
||||
|
||||
[FieldOffset( 0xE0 )]
|
||||
[FieldOffset(0xE0)]
|
||||
public byte* StringList;
|
||||
|
||||
[FieldOffset( 0xF8 )]
|
||||
[FieldOffset(0xF8)]
|
||||
public ushort ShpkOffset;
|
||||
|
||||
[FieldOffset( 0xFA )]
|
||||
[FieldOffset(0xFA)]
|
||||
public byte NumTex;
|
||||
|
||||
public byte* ShpkString
|
||||
=> StringList + ShpkOffset;
|
||||
|
||||
public byte* TexString( int idx )
|
||||
public byte* TexString(int idx)
|
||||
=> StringList + TexSpace[idx].PathOffset;
|
||||
|
||||
public bool TexIsDX11( int idx )
|
||||
public bool TexIsDX11(int idx)
|
||||
=> TexSpace[idx].Flags >= 0x8000;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 0x10)]
|
||||
public struct TextureEntry
|
||||
{
|
||||
[FieldOffset( 0x00 )]
|
||||
[FieldOffset(0x00)]
|
||||
public TextureResourceHandle* ResourceHandle;
|
||||
|
||||
[FieldOffset( 0x08 )]
|
||||
[FieldOffset(0x08)]
|
||||
public ushort PathOffset;
|
||||
|
||||
[FieldOffset( 0x0A )]
|
||||
[FieldOffset(0x0A)]
|
||||
public ushort Flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,39 +2,39 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
|||
|
||||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct RenderModel
|
||||
{
|
||||
[FieldOffset( 0x18 )]
|
||||
[FieldOffset(0x18)]
|
||||
public RenderModel* PreviousModel;
|
||||
|
||||
[FieldOffset( 0x20 )]
|
||||
[FieldOffset(0x20)]
|
||||
public RenderModel* NextModel;
|
||||
|
||||
[FieldOffset( 0x30 )]
|
||||
[FieldOffset(0x30)]
|
||||
public ResourceHandle* ResourceHandle;
|
||||
|
||||
[FieldOffset( 0x40 )]
|
||||
[FieldOffset(0x40)]
|
||||
public Skeleton* Skeleton;
|
||||
|
||||
[FieldOffset( 0x58 )]
|
||||
[FieldOffset(0x58)]
|
||||
public void** BoneList;
|
||||
|
||||
[FieldOffset( 0x60 )]
|
||||
[FieldOffset(0x60)]
|
||||
public int BoneListCount;
|
||||
|
||||
[FieldOffset( 0x70 )]
|
||||
[FieldOffset(0x70)]
|
||||
private void* UnkDXBuffer1;
|
||||
|
||||
[FieldOffset( 0x78 )]
|
||||
[FieldOffset(0x78)]
|
||||
private void* UnkDXBuffer2;
|
||||
|
||||
[FieldOffset( 0x80 )]
|
||||
[FieldOffset(0x80)]
|
||||
private void* UnkDXBuffer3;
|
||||
|
||||
[FieldOffset( 0x98 )]
|
||||
[FieldOffset(0x98)]
|
||||
public void** Materials;
|
||||
|
||||
[FieldOffset( 0xA0 )]
|
||||
[FieldOffset(0xA0)]
|
||||
public int MaterialCount;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ namespace Penumbra.Interop.Structs;
|
|||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct ResidentResourceManager
|
||||
{
|
||||
[FieldOffset( 0x00 )]
|
||||
[FieldOffset(0x00)]
|
||||
public void** VTable;
|
||||
|
||||
[FieldOffset( 0x08 )]
|
||||
[FieldOffset(0x08)]
|
||||
public void** ResourceListVTable;
|
||||
|
||||
[FieldOffset( 0x14 )]
|
||||
[FieldOffset(0x14)]
|
||||
public uint NumResources;
|
||||
|
||||
[FieldOffset( 0x18 )]
|
||||
[FieldOffset(0x18)]
|
||||
public ResourceHandle** ResourceList;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,45 +8,45 @@ using Penumbra.String.Classes;
|
|||
|
||||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct TextureResourceHandle
|
||||
{
|
||||
[FieldOffset( 0x0 )]
|
||||
[FieldOffset(0x0)]
|
||||
public ResourceHandle Handle;
|
||||
|
||||
[FieldOffset( 0x38 )]
|
||||
[FieldOffset(0x38)]
|
||||
public IntPtr Unk;
|
||||
|
||||
[FieldOffset( 0x118 )]
|
||||
[FieldOffset(0x118)]
|
||||
public Texture* KernelTexture;
|
||||
|
||||
[FieldOffset( 0x20 )]
|
||||
[FieldOffset(0x20)]
|
||||
public IntPtr NewKernelTexture;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct ShaderPackageResourceHandle
|
||||
{
|
||||
[FieldOffset( 0x0 )]
|
||||
[FieldOffset(0x0)]
|
||||
public ResourceHandle Handle;
|
||||
|
||||
[FieldOffset( 0xB0 )]
|
||||
[FieldOffset(0xB0)]
|
||||
public ShaderPackage* ShaderPackage;
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct ResourceHandle
|
||||
{
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct DataIndirection
|
||||
{
|
||||
[FieldOffset( 0x00 )]
|
||||
[FieldOffset(0x00)]
|
||||
public void** VTable;
|
||||
|
||||
[FieldOffset( 0x10 )]
|
||||
[FieldOffset(0x10)]
|
||||
public byte* DataPtr;
|
||||
|
||||
[FieldOffset( 0x28 )]
|
||||
[FieldOffset(0x28)]
|
||||
public ulong DataLength;
|
||||
}
|
||||
|
||||
|
|
@ -54,87 +54,83 @@ public unsafe struct ResourceHandle
|
|||
|
||||
public byte* FileNamePtr()
|
||||
{
|
||||
if( FileNameLength > SsoSize )
|
||||
{
|
||||
if (FileNameLength > SsoSize)
|
||||
return FileNameData;
|
||||
}
|
||||
|
||||
fixed( byte** name = &FileNameData )
|
||||
fixed (byte** name = &FileNameData)
|
||||
{
|
||||
return ( byte* )name;
|
||||
return (byte*)name;
|
||||
}
|
||||
}
|
||||
|
||||
public ByteString FileName()
|
||||
=> ByteString.FromByteStringUnsafe( FileNamePtr(), FileNameLength, true );
|
||||
=> ByteString.FromByteStringUnsafe(FileNamePtr(), FileNameLength, true);
|
||||
|
||||
public ReadOnlySpan< byte > FileNameAsSpan()
|
||||
=> new( FileNamePtr(), FileNameLength );
|
||||
public ReadOnlySpan<byte> FileNameAsSpan()
|
||||
=> new(FileNamePtr(), FileNameLength);
|
||||
|
||||
public bool GamePath( out Utf8GamePath path )
|
||||
=> Utf8GamePath.FromSpan( FileNameAsSpan(), out path );
|
||||
public bool GamePath(out Utf8GamePath path)
|
||||
=> Utf8GamePath.FromSpan(FileNameAsSpan(), out path);
|
||||
|
||||
[FieldOffset( 0x00 )]
|
||||
[FieldOffset(0x00)]
|
||||
public void** VTable;
|
||||
|
||||
[FieldOffset( 0x08 )]
|
||||
[FieldOffset(0x08)]
|
||||
public ResourceCategory Category;
|
||||
|
||||
[FieldOffset( 0x0C )]
|
||||
[FieldOffset(0x0C)]
|
||||
public ResourceType FileType;
|
||||
|
||||
[FieldOffset( 0x10 )]
|
||||
[FieldOffset(0x10)]
|
||||
public uint Id;
|
||||
|
||||
[FieldOffset( 0x28 )]
|
||||
[FieldOffset(0x28)]
|
||||
public uint FileSize;
|
||||
|
||||
[FieldOffset( 0x2C )]
|
||||
[FieldOffset(0x2C)]
|
||||
public uint FileSize2;
|
||||
|
||||
[FieldOffset( 0x34 )]
|
||||
[FieldOffset(0x34)]
|
||||
public uint FileSize3;
|
||||
|
||||
[FieldOffset( 0x48 )]
|
||||
[FieldOffset(0x48)]
|
||||
public byte* FileNameData;
|
||||
|
||||
[FieldOffset( 0x58 )]
|
||||
[FieldOffset(0x58)]
|
||||
public int FileNameLength;
|
||||
|
||||
[FieldOffset( 0xAC )]
|
||||
[FieldOffset(0xAC)]
|
||||
public uint RefCount;
|
||||
|
||||
// May return null.
|
||||
public static byte* GetData( ResourceHandle* handle )
|
||||
=> ( ( delegate* unmanaged< ResourceHandle*, byte* > )handle->VTable[ Offsets.ResourceHandleGetDataVfunc ] )( handle );
|
||||
public static byte* GetData(ResourceHandle* handle)
|
||||
=> ((delegate* unmanaged< ResourceHandle*, byte* >)handle->VTable[Offsets.ResourceHandleGetDataVfunc])(handle);
|
||||
|
||||
public static ulong GetLength( ResourceHandle* handle )
|
||||
=> ( ( delegate* unmanaged< ResourceHandle*, ulong > )handle->VTable[ Offsets.ResourceHandleGetLengthVfunc ] )( handle );
|
||||
public static ulong GetLength(ResourceHandle* handle)
|
||||
=> ((delegate* unmanaged< ResourceHandle*, ulong >)handle->VTable[Offsets.ResourceHandleGetLengthVfunc])(handle);
|
||||
|
||||
|
||||
// Only use these if you know what you are doing.
|
||||
// Those are actually only sure to be accessible for DefaultResourceHandles.
|
||||
[FieldOffset( 0xB0 )]
|
||||
[FieldOffset(0xB0)]
|
||||
public DataIndirection* Data;
|
||||
|
||||
[FieldOffset( 0xB8 )]
|
||||
[FieldOffset(0xB8)]
|
||||
public uint DataLength;
|
||||
|
||||
public (IntPtr Data, int Length) GetData()
|
||||
=> Data != null
|
||||
? ( ( IntPtr )Data->DataPtr, ( int )Data->DataLength )
|
||||
: ( IntPtr.Zero, 0 );
|
||||
? ((IntPtr)Data->DataPtr, (int)Data->DataLength)
|
||||
: (IntPtr.Zero, 0);
|
||||
|
||||
public bool SetData( IntPtr data, int length )
|
||||
public bool SetData(IntPtr data, int length)
|
||||
{
|
||||
if( Data == null )
|
||||
{
|
||||
if (Data == null)
|
||||
return false;
|
||||
}
|
||||
|
||||
Data->DataPtr = length != 0 ? ( byte* )data : null;
|
||||
Data->DataLength = ( ulong )length;
|
||||
DataLength = ( uint )length;
|
||||
Data->DataPtr = length != 0 ? (byte*)data : null;
|
||||
Data->DataLength = (ulong)length;
|
||||
DataLength = (uint)length;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,17 @@
|
|||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct SeFileDescriptor
|
||||
{
|
||||
[FieldOffset( 0x00 )]
|
||||
[FieldOffset(0x00)]
|
||||
public FileMode FileMode;
|
||||
|
||||
[FieldOffset( 0x30 )]
|
||||
public void* FileDescriptor; //
|
||||
[FieldOffset(0x30)]
|
||||
public void* FileDescriptor;
|
||||
|
||||
[FieldOffset( 0x50 )]
|
||||
public ResourceHandle* ResourceHandle; //
|
||||
[FieldOffset(0x50)]
|
||||
public ResourceHandle* ResourceHandle;
|
||||
|
||||
|
||||
[FieldOffset( 0x70 )]
|
||||
public char Utf16FileName; //
|
||||
}
|
||||
[FieldOffset(0x70)]
|
||||
public char Utf16FileName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@ using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
|||
|
||||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
public unsafe static class TextureUtility
|
||||
public static unsafe class TextureUtility
|
||||
{
|
||||
private static readonly Functions Funcs = new();
|
||||
|
||||
public static Texture* Create2D(Device* device, int* size, byte mipLevel, uint textureFormat, uint flags, uint unk)
|
||||
=> ((delegate* unmanaged<Device*, int*, byte, uint, uint, uint, Texture*>)Funcs.TextureCreate2D)(device, size, mipLevel, textureFormat, flags, unk);
|
||||
=> ((delegate* unmanaged<Device*, int*, byte, uint, uint, uint, Texture*>)Funcs.TextureCreate2D)(device, size, mipLevel, textureFormat,
|
||||
flags, unk);
|
||||
|
||||
public static bool InitializeContents(Texture* texture, void* contents)
|
||||
=> ((delegate* unmanaged<Texture*, void*, bool>)Funcs.TextureInitializeContents)(texture, contents);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
namespace Penumbra.Interop.Structs;
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public unsafe struct VfxParams
|
||||
{
|
||||
[FieldOffset( 0x118 )]
|
||||
[FieldOffset(0x118)]
|
||||
public uint GameObjectId;
|
||||
|
||||
[FieldOffset( 0x11C )]
|
||||
[FieldOffset(0x11C)]
|
||||
public byte GameObjectType;
|
||||
|
||||
[FieldOffset( 0xD0 )]
|
||||
[FieldOffset(0xD0)]
|
||||
public ushort TargetCount;
|
||||
|
||||
[FieldOffset( 0x120 )]
|
||||
[FieldOffset(0x120)]
|
||||
public fixed ulong Target[16];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue