Skip to content

Commit 19b06ff

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents 5f8961d + d85fcff commit 19b06ff

24 files changed

Lines changed: 737 additions & 43 deletions

FFXIVClientStructs/FFXIV/Client/Game/Character/Character.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public unsafe partial struct Character {
3131

3232
// 0x1AA8: start of some substructure
3333
[FieldOffset(0x1B28)] public ModelContainer ModelContainer;
34+
[FieldOffset(0x1B80)] public RepresentationContainer RepresentationContainer;
3435

3536
/// <remarks> Instance ID of an Event NPC. Used by QuestEventHandler. Seen for Event NPCs that turn into Battle NPCs (during quests, for example.) </remarks>
3637
[FieldOffset(0x1BC0)] public uint EventNpcInstanceId;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace FFXIVClientStructs.FFXIV.Client.Game.Character;
2+
3+
// Client::Game::Character::RepresentationContainer
4+
// Client::Game::Character::ContainerInterface
5+
[GenerateInterop]
6+
[Inherits<ContainerInterface>]
7+
[StructLayout(LayoutKind.Explicit, Size = 0x30)]
8+
public unsafe partial struct RepresentationContainer {
9+
// not 100% on these
10+
// 1 = Normal
11+
// 2 = (Skips everything??)
12+
// 3 = Blacklisted (using NameOverride)
13+
// 4 = Alliance Member, Friend, in Custom Match or in Duel
14+
// 5 = Cross-realm Party Member
15+
[FieldOffset(0x10)] public byte NameType;
16+
17+
[FieldOffset(0x18)] public Utf8String* NameOverride; // "Unknown"
18+
[FieldOffset(0x20)] public float UpdateTimer;
19+
[FieldOffset(0x24)] private byte Unk24;
20+
[FieldOffset(0x25)] private ushort Unk25; // some flags based on Status
21+
[FieldOffset(0x28)] private byte Unk28; // some flags for Scheduler
22+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace FFXIVClientStructs.FFXIV.Client.Game.Network;
2+
3+
[GenerateInterop]
4+
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
5+
public partial struct ActorCastPacket {
6+
[FieldOffset(0x00)] public ushort SpellId;
7+
[FieldOffset(0x02)] public byte ActionType;
8+
[FieldOffset(0x03)] public byte OmenDelay; // The value gets divided by 10.0f
9+
[FieldOffset(0x04)] public uint ActionId;
10+
[FieldOffset(0x08)] public float CastTime;
11+
[FieldOffset(0x0C)] public uint TargetEntityId;
12+
[FieldOffset(0x10)] public ushort RotationInt; // Quantized Rotation
13+
[FieldOffset(0x12)] public bool Interruptible;
14+
[FieldOffset(0x14)] public uint BallistaEntityId;
15+
[FieldOffset(0x18), FixedSizeArray] internal FixedSizeArray3<ushort> _positionInt; // Quantized Position
16+
}

FFXIVClientStructs/FFXIV/Client/Game/Object/EventObject.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace FFXIVClientStructs.FFXIV.Client.Game.Object;
88
public partial struct EventObject {
99
[FieldOffset(0x1A0), CExporterExcel("EObj")] public nint EObjRowPtr;
1010
[FieldOffset(0x1A8), CExporterExcel("ExportedSG")] public nint ExportedSGRowPtr;
11+
[FieldOffset(0x1B2)] public ushort SharedTimelineState; // ActorControl category 0x199 (SetSharedTimelineState) sets this field
12+
[FieldOffset(0x1B8)] public byte Flags;
1113

1214
[MemberFunction("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 4D 85 F6 0F 84 ?? ?? ?? ?? 8B 44 24 70 BE ?? ?? ?? ??")]
1315
public partial void PlayAnimation(uint entityId, uint actionId, ulong unknown);

FFXIVClientStructs/FFXIV/Client/Game/WKS/WKSMissionModule.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ public unsafe partial struct MissionState {
2020
/// <remarks> RowId of WKSMissionUnit sheet. </remarks>
2121
[FieldOffset(0x00)] public ushort MissionUnitRowId;
2222

23-
[FieldOffset(0x0C)] public ushort Score; // TODO: uint
24-
23+
[FieldOffset(0x0C), Obsolete("Use ScoreUInt", true)] public ushort Score;
24+
[FieldOffset(0x0C)] public uint ScoreUInt; // TODO: change name back to Score...
2525
[FieldOffset(0x10)] public MissionRank Rank;
2626
[FieldOffset(0x14)] private byte Unk14; // bool? status?
2727

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
namespace FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
2+
3+
/// <summary>
4+
/// Records rendering commands to be executed later by the <see cref="ImmediateContext"/>.
5+
/// </summary>
6+
/// <remarks>
7+
/// Threads have their own Context, accessed via <see cref="ThreadLocals.GraphicsKernelContext"/>.
8+
/// </remarks>
9+
[GenerateInterop]
10+
[StructLayout(LayoutKind.Explicit, Size = 0x2F78)]
11+
public unsafe partial struct Context {
12+
[BitField<byte>(nameof(CurrentSubViewIndex), 28, 4)]
13+
[FieldOffset(0x008)] private uint _flags;
14+
[FieldOffset(0x00C)] public int ViewIndex;
15+
[FieldOffset(0x010)] public void* CommandAllocationBase;
16+
17+
[FieldOffset(0x840)] public ulong CommandAllocationUsedSize;
18+
[FieldOffset(0x848)] public ulong AllocationBase;
19+
[FieldOffset(0x850)] public ulong AllocationUsedSize;
20+
21+
[MemberFunction("4C 8B D1 4C 8D 42 0F")]
22+
public partial void* AllocateCommand(ulong size);
23+
24+
[MemberFunction("4C 8B C9 4D 8D 50 0F")]
25+
public partial void* AllocateSpecificCommand(RenderCommandType commandType, ulong size);
26+
27+
[MemberFunction("E8 ?? ?? ?? ?? 8B 6E 6C")]
28+
public partial void PushBackCommand(void* command);
29+
30+
[MemberFunction("E8 ?? ?? ?? ?? 8D 56 38")]
31+
public partial void SetRenderTargets(int renderTargetCount, Texture** renderTargetTextures, Texture* depthStencilTexture, short a4, short a5, short a6, short a7); // last params believed to be a rectangle
32+
}

FFXIVClientStructs/FFXIV/Client/Graphics/Kernel/Device.cs

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using FFXIVClientStructs.FFXIV.Common.Math;
2+
13
namespace FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
24

35
// Client::Graphics::Kernel::Device
@@ -10,7 +12,7 @@ public unsafe partial struct Device {
1012
[StaticAddress("48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 7B 08 00", 3, isPointer: true)]
1113
public static partial Device* Instance();
1214

13-
[FieldOffset(0x8)] public void* ContextArray; // Client::Graphics::Kernel::Context array
15+
[FieldOffset(0x8)] public void* ContextArray; // TODO: We have a struct for this now (breaking change)
1416
[FieldOffset(0x10)] public void* RenderThread; // Client::Graphics::Kernel::RenderThread
1517
[FieldOffset(0x28)] private CallbackManager* Unk28;
1618
[FieldOffset(0x30)] private CallbackManager* Unk30;
@@ -71,7 +73,7 @@ public unsafe partial struct Device {
7173
// Client::Graphics::Kernel::Device::CallbackManager
7274
[GenerateInterop]
7375
[StructLayout(LayoutKind.Explicit, Size = 0x40)]
74-
public unsafe partial struct CallbackManager {
76+
public partial struct CallbackManager {
7577
[FieldOffset(0x8)] public void* Lock; // CRITICAL_SECTION
7678

7779
[FieldOffset(0x30)] public Entry* Entries;
@@ -89,7 +91,7 @@ public unsafe partial struct CallbackManager {
8991

9092
// Unsure about the names of things inside CallbackManager though
9193
[StructLayout(LayoutKind.Explicit, Size = 0x10)]
92-
public unsafe partial struct Entry {
94+
public struct Entry {
9395
[FieldOffset(0x0)] public void* Function;
9496
[FieldOffset(0x8)] public void* Context;
9597
}
@@ -103,44 +105,68 @@ public unsafe struct RenderCommandBufferGroup {
103105
[FieldOffset(0x8), CExporterUnion("RenderCommand")] public RenderCommandSetTarget* SetTargetCommand;
104106
[FieldOffset(0x8), CExporterUnion("RenderCommand")] public RenderCommandViewport* ViewportCommand;
105107
[FieldOffset(0x8), CExporterUnion("RenderCommand")] public RenderCommandScissorsRect* ScissorsRectCommand;
106-
[FieldOffset(0x8), CExporterUnion("RenderCommand")] public RenderCommandClearDepth* ClearDepthCommand;
108+
[FieldOffset(0x8), CExporterUnion("RenderCommand"), Obsolete("Use ClearCommand.")] public RenderCommandClearDepth* ClearDepthCommand;
109+
[FieldOffset(0x8), CExporterUnion("RenderCommand")] public RenderCommandClear* ClearCommand;
110+
}
111+
112+
public enum RenderCommandType : int {
113+
SetTarget = 0,
114+
Viewport = 1,
115+
MultiViewport = 2,
116+
ScissorRect = 3,
117+
Clear = 4,
107118
}
108119

109120
[GenerateInterop]
110121
[StructLayout(LayoutKind.Explicit, Size = 0x40)]
111122
public unsafe partial struct RenderCommandSetTarget {
112-
[FieldOffset(0x0)] public int SwitchType;
123+
[FieldOffset(0x0)] public RenderCommandType Type;
113124
[FieldOffset(0x4)] public int RenderTargetCount;
114-
[FieldOffset(0x8), FixedSizeArray] internal FixedSizeArray4<Pointer<Texture>> _renderTargets;
115-
[FieldOffset(0x28)] public Texture* DepthBuffer;
125+
[FieldOffset(0x8), FixedSizeArray] internal FixedSizeArray5<Pointer<Texture>> _renderTargets;
126+
[FieldOffset(0x30)] public Texture* DepthBuffer;
116127
[FieldOffset(0x38)] private float Unk0;
117128
[FieldOffset(0x3C)] private float Unk1;
129+
130+
[FieldOffset(0x0), Obsolete("Use Type instead.")] public int SwitchType;
118131
}
119132

120-
[GenerateInterop]
121133
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
122-
public unsafe partial struct RenderCommandViewport {
123-
[FieldOffset(0x0)] public int SwitchType;
124-
[FieldOffset(0x04)] public int TopLeftY;
125-
[FieldOffset(0x08)] public int TopLeftX;
126-
[FieldOffset(0x0C)] public int BottomRightY;
127-
[FieldOffset(0x10)] public int BottomRightX;
134+
public struct RenderCommandViewport {
135+
[FieldOffset(0x0)] public RenderCommandType Type;
136+
[FieldOffset(0x4)] public IntRectangle ViewportRect;
128137
[FieldOffset(0x14)] public float MinDepth;
129138
[FieldOffset(0x18)] public float MaxDepth;
139+
140+
[FieldOffset(0x0), Obsolete("Use Type instead.")] public int SwitchType;
141+
[FieldOffset(0x04), Obsolete("Use ViewportRect.Left.")] public int TopLeftY;
142+
[FieldOffset(0x08), Obsolete("Use ViewportRect.Top.")] public int TopLeftX;
143+
[FieldOffset(0x0C), Obsolete("Use ViewportRect.Right.")] public int BottomRightY;
144+
[FieldOffset(0x10), Obsolete("Use ViewportRect.Bottom.")] public int BottomRightX;
130145
}
131146

132147
[GenerateInterop]
133-
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
134-
public unsafe partial struct RenderCommandScissorsRect {
148+
[StructLayout(LayoutKind.Explicit, Size = 0x80)]
149+
public partial struct RenderCommandMultiViewport {
135150
[FieldOffset(0x0)] public int SwitchType;
136-
[FieldOffset(0x4)] public int Left;
137-
[FieldOffset(0x8)] public int Top;
138-
[FieldOffset(0xC)] public int Right;
139-
[FieldOffset(0x10)] public int Bottom;
151+
[FieldOffset(0x4), FixedSizeArray] internal FixedSizeArray5<IntRectangle> _viewportRects;
152+
[FieldOffset(0x54), FixedSizeArray] internal FixedSizeArray5<float> _minDepths;
153+
[FieldOffset(0x68), FixedSizeArray] internal FixedSizeArray5<float> _maxDepths;
154+
[FieldOffset(0x7C)] public uint ViewportCount;
140155
}
141156

142-
[GenerateInterop]
143-
[StructLayout(LayoutKind.Explicit, Size = 0x40)]
157+
[StructLayout(LayoutKind.Explicit, Size = 0x20)]
158+
public struct RenderCommandScissorsRect {
159+
[FieldOffset(0x0)] public RenderCommandType Type;
160+
[FieldOffset(0x4)] public IntRectangle ScissorRect;
161+
162+
[FieldOffset(0x0), Obsolete("Use Type instead.")] public int SwitchType;
163+
[FieldOffset(0x4), Obsolete("Use ScissorRect.Left.")] public int Left;
164+
[FieldOffset(0x8), Obsolete("Use ScissorRect.Top.")] public int Top;
165+
[FieldOffset(0xC), Obsolete("Use ScissorRect.Right.")] public int Right;
166+
[FieldOffset(0x10), Obsolete("Use ScissorRect.Bottom.")] public int Bottom;
167+
}
168+
169+
[StructLayout(LayoutKind.Explicit, Size = 0x40), Obsolete("Use RenderCommandClear.")]
144170
public unsafe partial struct RenderCommandClearDepth {
145171
[FieldOffset(0x0)] public int SwitchType;
146172
[FieldOffset(0x4)] public float ClearType;
@@ -158,3 +184,25 @@ public unsafe partial struct RenderCommandClearDepth {
158184
[FieldOffset(0x34)] public float MinZ;
159185
[FieldOffset(0x38)] public float MaxZ;
160186
}
187+
188+
public enum ClearFlags : uint {
189+
None = 0,
190+
Color = 1 << 0,
191+
Depth = 1 << 1,
192+
Stencil = 1 << 2,
193+
}
194+
195+
[StructLayout(LayoutKind.Explicit, Size = 0x38)]
196+
public unsafe struct RenderCommandClear {
197+
[FieldOffset(0x0)] public RenderCommandType Type;
198+
[FieldOffset(0x4)] public ClearFlags ClearFlags;
199+
[FieldOffset(0x8)] public float ColorR;
200+
[FieldOffset(0xC)] public float ColorG;
201+
[FieldOffset(0x10)] public float ColorB;
202+
[FieldOffset(0x14)] public float ColorA;
203+
[FieldOffset(0x18)] public float ClearDepth;
204+
[FieldOffset(0x1C)] public byte ClearStencil;
205+
[FieldOffset(0x1D)] public byte StencilReference;
206+
[FieldOffset(0x20)] public IntRectangle* ClearRectanglePtr; // optional, generally points at ClearRectangle if set
207+
[FieldOffset(0x28)] public IntRectangle ClearRectangle;
208+
}
Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using FFXIVClientStructs.FFXIV.Common.Math;
2+
13
namespace FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
24

35
// Client::Graphics::Kernel::ImmediateContext
@@ -8,10 +10,86 @@ namespace FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
810
public unsafe partial struct ImmediateContext {
911
// Offset 0 is ID3D11DeviceContext
1012

11-
// <remark>
12-
// Reset and assigned each rendered frame from Device->SwapChain->BackBuffer
13-
// </remark>
13+
[FieldOffset(0x08)] public Rectangle CurrentScissorRect;
14+
15+
[Obsolete("Not necessarily the backbuffer, just the current primary render target. Prefer CurrentRenderTargets.")]
1416
[FieldOffset(0x28)] public Texture* BackBufferReference;
17+
/// <summary>
18+
/// The currently bound render targets.
19+
/// </summary>
20+
[FieldOffset(0x28)] internal FixedSizeArray5<Pointer<Texture>> _currentRenderTargets;
21+
/// <summary>
22+
/// The currently bound depth stencil buffer, if any.
23+
/// </summary>
24+
[FieldOffset(0x50)] public Texture* CurrentDepthStencilBuffer;
25+
26+
[FieldOffset(0xAC)] public uint CurrentDepthState; // The 5 bits of depth state in PackedDepthStencilDesc with the stencil fields masked out
27+
[FieldOffset(0xB0)] public PackedDepthStencilDesc CurrentStencilState; // With the depth fields masked out
28+
// 0xC8: InputLayoutDesc
29+
30+
[FieldOffset(0xD0)] public VertexShader* CurrentVertexShader;
31+
[FieldOffset(0x1B8)] public PixelShader* CurrentPixelShader;
32+
33+
// Certain types of complex clearing needs to be done by manually drawing to the render targets & depth buffer.
34+
[FieldOffset(0x700)] public VertexShader* ManualClearQuadVertexShader;
35+
[FieldOffset(0x708)] public PixelShader* ManualClearQuadPixelShader;
36+
// 0x710: ManualClearQuad???
37+
// 0x718: ManualClearQuadInputLayoutDesc
38+
[FieldOffset(0x730)] public GeometryShader* CurrentGeometryShader;
39+
[FieldOffset(0xB20)] public HullShader* CurrentHullShader;
40+
41+
[FieldOffset(0xBE8), CExporterTypeForce("ID3D11DeviceContext*", true)] public void* D3D11DeviceContext;
42+
43+
[FieldOffset(0xF10)] public DomainShader* CurrentDomainShader;
44+
45+
[FieldOffset(0x17B3)] public byte BlendStateFlag; // Might be a bool to force creation of an underlying ID3D11BlendState*
46+
[FieldOffset(0x17B4)] public PackedBlendStateDesc CurrentBlendState;
47+
[FieldOffset(0x17B8), CExporterTypeForce("ID3D11DeviceContext*", true)] public void* D3D11DeviceContext_2;
48+
49+
//[FieldOffset(0x1D70)] public InputLayout* CurrentInputLayout;
50+
[FieldOffset(0x17D8), CExporterTypeForce("D3D11_PRIMITIVE_TOPOLOGY", true)] public int CurrentPrimitiveTopology;
51+
52+
[MemberFunction("E8 ?? ?? ?? ?? 49 8D 47 58")]
53+
public partial void SetBlendState(PackedBlendStateDesc blendState);
54+
55+
[MemberFunction("E8 ?? ?? ?? ?? 41 8B 56 1C 48 8B CE")]
56+
public partial void SetDepthStencilState(byte obfuscatedDepthState, PackedDepthStencilDesc stencilState);
57+
58+
// Along with the given packed rasterizer state, the following constant values are also used:
59+
// FrontCounterClockwise = true
60+
// DepthClipEnable = true
61+
// DepthBiasClamp = 100.0f
62+
// AntialiasedLineEnable = false
63+
[MemberFunction("E8 ?? ?? ?? ?? 49 8B 46 20 48 8B CE")]
64+
public partial void SetRasterizerState(PackedRasterizerStateDesc rasterizerState);
65+
66+
[MemberFunction("E8 ?? ?? ?? ?? 4D 8B 46 68")]
67+
public partial void SetVertexShader(VertexShader* vertexShader, void** constantBuffers);
68+
69+
[MemberFunction("E8 ?? ?? ?? ?? 4D 8B 46 78")]
70+
public partial void SetPixelShader(PixelShader* pixelShader, void** constantBuffers);
71+
72+
[MemberFunction("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 8B 57 7C")]
73+
public partial void SetViewport(IntRectangle* viewportRectangle, float minDepth, float maxDepth);
74+
75+
[MemberFunction("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 8B D7 48 8B CB E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 83 7F")]
76+
public partial void SetMultiViewports(uint viewportCount, IntRectangle* viewports, float* minDepths, float* maxDepths);
77+
78+
[MemberFunction("E9 ?? ?? ?? ?? 48 8B 4A 10")]
79+
public partial void SetDefaultState();
80+
81+
[MemberFunction("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 48 83 7F ?? ?? 0F 84 ?? ?? ?? ?? 48 83 7F")]
82+
public partial void DoClearCommandViaDraw(RenderCommandClear* clearCommand);
83+
84+
[MemberFunction("48 89 6C 24 ?? 56 48 83 EC 40 48 83 7A")] // inlined in some places
85+
public partial void DoClearCommand(RenderCommandClear* clearCommand);
86+
87+
[MemberFunction("E8 ?? ?? ?? ?? 48 8B 4B 30 FF 15")]
88+
public partial void ProcessCommands(RenderCommandBufferGroup* renderCommands, uint renderCommandCount);
89+
90+
[MemberFunction("E8 ?? ?? ?? ?? 48 8B 7B 18 45 33 FF")]
91+
public partial void PreprocessCommands(RenderCommandBufferGroup* renderCommands, uint renderCommandCount);
1592

16-
[FieldOffset(0xBE8)] public void* D3D11DeviceContext;
93+
[MemberFunction("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 0F B6 83 ?? ?? ?? ?? 3C 01 73 70")]
94+
public partial void ExecuteCommands();
1795
}

0 commit comments

Comments
 (0)