muffin v7.5.5
This commit is contained in:
parent
a8f2c1df37
commit
6266f9e6b7
110 changed files with 14907 additions and 6073 deletions
26
Auspex/Auspex.Lighting.Internal/GameLightData.cs
Normal file
26
Auspex/Auspex.Lighting.Internal/GameLightData.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Auspex.Lighting.Internal;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 160)]
|
||||
internal struct GameLightData
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public unsafe GameLightVTable* VirtualTable;
|
||||
|
||||
[FieldOffset(80)]
|
||||
public LightTransform Transform;
|
||||
|
||||
[FieldOffset(112)]
|
||||
public Vector3 Scale;
|
||||
|
||||
[FieldOffset(136)]
|
||||
public byte Flags00;
|
||||
|
||||
[FieldOffset(137)]
|
||||
public byte Flags01;
|
||||
|
||||
[FieldOffset(144)]
|
||||
public unsafe LightRenderData* RenderObject;
|
||||
}
|
||||
13
Auspex/Auspex.Lighting.Internal/GameLightVTable.cs
Normal file
13
Auspex/Auspex.Lighting.Internal/GameLightVTable.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Auspex.Lighting.Internal;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct GameLightVTable
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public unsafe delegate* unmanaged<GameLightData*, bool, void> Destructor;
|
||||
|
||||
[FieldOffset(8)]
|
||||
public unsafe delegate* unmanaged<GameLightData*, void> Cleanup;
|
||||
}
|
||||
56
Auspex/Auspex.Lighting.Internal/LightNativeBridge.cs
Normal file
56
Auspex/Auspex.Lighting.Internal/LightNativeBridge.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
namespace Auspex.Lighting.Internal;
|
||||
|
||||
internal static class LightNativeBridge
|
||||
{
|
||||
public unsafe delegate GameLightData* SpawnDelegate(GameLightData* light);
|
||||
|
||||
public unsafe delegate void CreateDelegate(GameLightData* light);
|
||||
|
||||
public unsafe delegate void FinalizeDelegate(GameLightData* light);
|
||||
|
||||
public unsafe delegate void UpdateCullingDelegate(GameLightData* light);
|
||||
|
||||
public unsafe delegate void UpdateMaterialDelegate(GameLightData* light);
|
||||
|
||||
public unsafe delegate void UpdateRangeDelegate(LightRenderData* renderData);
|
||||
|
||||
public const string SpawnSig = "E8 ?? ?? ?? ?? 48 89 84 ?? ?? ?? ?? ?? 48 85 C0 0F ?? ?? ?? ?? ?? 48 8B C8";
|
||||
|
||||
public static SpawnDelegate Spawn;
|
||||
|
||||
public const string CreateSig = "E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B D3 E8 ?? ?? ?? ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? 40 0F";
|
||||
|
||||
public static CreateDelegate Create;
|
||||
|
||||
public const string FinalizeSig = "F6 41 38 01 ?? ?? 48 8B ?? ?? ?? ?? ?? 48";
|
||||
|
||||
public new static FinalizeDelegate Finalize;
|
||||
|
||||
public const string UpdateCullingSig = "48 89 5C 24 ?? 57 48 83 EC 40 48 8B B9 ?? ?? ?? ??";
|
||||
|
||||
public static UpdateCullingDelegate UpdateCulling;
|
||||
|
||||
public const string UpdateMaterialSig = "40 53 48 83 EC 20 0F B6 81 ?? ?? ?? ?? 48 8B D9 A8 04 75 45 0C 04 B2 05";
|
||||
|
||||
public static UpdateMaterialDelegate UpdateMaterial;
|
||||
|
||||
public const string UpdateRangeSig = "E8 ?? ?? ?? ?? 48 8D 8F ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 8D 8F ?? ?? ?? ?? 48 8D 55";
|
||||
|
||||
public static UpdateRangeDelegate UpdateRange;
|
||||
|
||||
internal static void Initialize()
|
||||
{
|
||||
SpawnDelegate spawn = SigScanHelper.Scan<SpawnDelegate>("E8 ?? ?? ?? ?? 48 89 84 ?? ?? ?? ?? ?? 48 85 C0 0F ?? ?? ?? ?? ?? 48 8B C8", "Spawn");
|
||||
CreateDelegate create = SigScanHelper.Scan<CreateDelegate>("E8 ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 8B D3 E8 ?? ?? ?? ?? 48 8B CB E8 ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? 40 0F", "Create");
|
||||
FinalizeDelegate finalize = SigScanHelper.Scan<FinalizeDelegate>("F6 41 38 01 ?? ?? 48 8B ?? ?? ?? ?? ?? 48", "Finalize");
|
||||
UpdateCullingDelegate updateCulling = SigScanHelper.Scan<UpdateCullingDelegate>("48 89 5C 24 ?? 57 48 83 EC 40 48 8B B9 ?? ?? ?? ??", "UpdateCulling");
|
||||
UpdateMaterialDelegate updateMaterial = SigScanHelper.Scan<UpdateMaterialDelegate>("40 53 48 83 EC 20 0F B6 81 ?? ?? ?? ?? 48 8B D9 A8 04 75 45 0C 04 B2 05", "UpdateMaterial");
|
||||
UpdateRangeDelegate updateRange = SigScanHelper.Scan<UpdateRangeDelegate>("E8 ?? ?? ?? ?? 48 8D 8F ?? ?? ?? ?? FF 15 ?? ?? ?? ?? 48 8D 8F ?? ?? ?? ?? 48 8D 55", "UpdateRange");
|
||||
Spawn = spawn;
|
||||
Create = create;
|
||||
Finalize = finalize;
|
||||
UpdateCulling = updateCulling;
|
||||
UpdateMaterial = updateMaterial;
|
||||
UpdateRange = updateRange;
|
||||
}
|
||||
}
|
||||
47
Auspex/Auspex.Lighting.Internal/LightRenderData.cs
Normal file
47
Auspex/Auspex.Lighting.Internal/LightRenderData.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Auspex.Lighting.Internal;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 160)]
|
||||
internal struct LightRenderData
|
||||
{
|
||||
[FieldOffset(24)]
|
||||
public AxLightFlags Flags;
|
||||
|
||||
[FieldOffset(28)]
|
||||
public AxLightType EmissionType;
|
||||
|
||||
[FieldOffset(32)]
|
||||
public unsafe LightTransform* Transform;
|
||||
|
||||
[FieldOffset(40)]
|
||||
public Vector3 Color;
|
||||
|
||||
[FieldOffset(52)]
|
||||
public float Intensity;
|
||||
|
||||
[FieldOffset(96)]
|
||||
public float ShadowPlaneNear;
|
||||
|
||||
[FieldOffset(100)]
|
||||
public float ShadowPlaneFar;
|
||||
|
||||
[FieldOffset(104)]
|
||||
public AxFalloffType FalloffType;
|
||||
|
||||
[FieldOffset(128)]
|
||||
public float Falloff;
|
||||
|
||||
[FieldOffset(132)]
|
||||
public float LightAngle;
|
||||
|
||||
[FieldOffset(136)]
|
||||
public float FalloffAngle;
|
||||
|
||||
[FieldOffset(140)]
|
||||
public float Range;
|
||||
|
||||
[FieldOffset(144)]
|
||||
public float CharacterShadowRange;
|
||||
}
|
||||
17
Auspex/Auspex.Lighting.Internal/LightTransform.cs
Normal file
17
Auspex/Auspex.Lighting.Internal/LightTransform.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Auspex.Lighting.Internal;
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 48)]
|
||||
internal struct LightTransform
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public Vector3 Position;
|
||||
|
||||
[FieldOffset(16)]
|
||||
public Quaternion Rotation;
|
||||
|
||||
[FieldOffset(32)]
|
||||
public Vector3 Scale;
|
||||
}
|
||||
205
Auspex/Auspex.Lighting.Internal/NativeLightHandle.cs
Normal file
205
Auspex/Auspex.Lighting.Internal/NativeLightHandle.cs
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Memory;
|
||||
|
||||
namespace Auspex.Lighting.Internal;
|
||||
|
||||
internal sealed class NativeLightHandle : IDisposable
|
||||
{
|
||||
private unsafe GameLightData* data;
|
||||
|
||||
private Vector3 position;
|
||||
|
||||
private Quaternion rotation;
|
||||
|
||||
private Vector3 color;
|
||||
|
||||
private float intensity;
|
||||
|
||||
private float range;
|
||||
|
||||
private float lightAngle;
|
||||
|
||||
private float falloffAngle;
|
||||
|
||||
private AxLightFlags flags;
|
||||
|
||||
private AxFalloffType falloffType;
|
||||
|
||||
private float falloffPower;
|
||||
|
||||
private float shadowNear;
|
||||
|
||||
private float shadowFar;
|
||||
|
||||
private float charaShadowRange;
|
||||
|
||||
public unsafe static NativeLightHandle Create(Vector3 position, AxLightType lightType, AxLightConfig config)
|
||||
{
|
||||
GameLightData* ptr = IMemorySpace.GetDefaultSpace()->Malloc<GameLightData>(8uL);
|
||||
if (LightNativeBridge.Spawn(ptr) == null)
|
||||
{
|
||||
IMemorySpace.Free(ptr, (ulong)sizeof(GameLightData));
|
||||
throw new InvalidOperationException("Failed to spawn game light");
|
||||
}
|
||||
LightNativeBridge.Create(ptr);
|
||||
LightNativeBridge.Finalize(ptr);
|
||||
((long*)ptr)[7] |= 2L;
|
||||
LightRenderData* renderObject = ptr->RenderObject;
|
||||
if (renderObject == null)
|
||||
{
|
||||
IMemorySpace.Free(ptr, (ulong)sizeof(GameLightData));
|
||||
throw new InvalidOperationException("Game did not create RenderObject for light");
|
||||
}
|
||||
renderObject->Transform = &ptr->Transform;
|
||||
renderObject->EmissionType = lightType;
|
||||
renderObject->Color = config.Color;
|
||||
renderObject->Intensity = config.Intensity;
|
||||
renderObject->Range = config.Range;
|
||||
renderObject->FalloffType = config.FalloffType;
|
||||
renderObject->Falloff = config.FalloffPower;
|
||||
renderObject->LightAngle = config.LightAngle;
|
||||
renderObject->FalloffAngle = config.FalloffAngle;
|
||||
renderObject->CharacterShadowRange = config.CharaShadowRange;
|
||||
renderObject->ShadowPlaneNear = config.ShadowNear;
|
||||
renderObject->ShadowPlaneFar = config.ShadowFar;
|
||||
renderObject->Flags = config.Flags;
|
||||
LightNativeBridge.UpdateRange(renderObject);
|
||||
Quaternion quaternion = config.Rotation ?? Quaternion.Identity;
|
||||
Unsafe.Write<Vector3>((void*)(&ptr->Transform.Position), position);
|
||||
Unsafe.Write<Quaternion>((void*)(&ptr->Transform.Rotation), quaternion);
|
||||
ptr->Scale = Vector3.One;
|
||||
return new NativeLightHandle
|
||||
{
|
||||
data = ptr,
|
||||
position = position,
|
||||
rotation = quaternion,
|
||||
color = config.Color,
|
||||
intensity = config.Intensity,
|
||||
range = config.Range,
|
||||
lightAngle = config.LightAngle,
|
||||
falloffAngle = config.FalloffAngle,
|
||||
flags = config.Flags,
|
||||
falloffType = config.FalloffType,
|
||||
falloffPower = config.FalloffPower,
|
||||
shadowNear = config.ShadowNear,
|
||||
shadowFar = config.ShadowFar,
|
||||
charaShadowRange = config.CharaShadowRange
|
||||
};
|
||||
}
|
||||
|
||||
public unsafe void UpdatePosition(Vector3 newPosition)
|
||||
{
|
||||
if (data != null && !(position == newPosition))
|
||||
{
|
||||
position = newPosition;
|
||||
Unsafe.Write<Vector3>((void*)(&data->Transform.Position), newPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateRotation(Quaternion newRotation)
|
||||
{
|
||||
if (data != null && !(rotation == newRotation))
|
||||
{
|
||||
rotation = newRotation;
|
||||
Unsafe.Write<Quaternion>((void*)(&data->Transform.Rotation), newRotation);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateColor(Vector3 newColor)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && !(color == newColor))
|
||||
{
|
||||
color = newColor;
|
||||
data->RenderObject->Color = newColor;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateIntensity(float newIntensity)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && intensity != newIntensity)
|
||||
{
|
||||
intensity = newIntensity;
|
||||
data->RenderObject->Intensity = newIntensity;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateRange(float newRange)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && range != newRange)
|
||||
{
|
||||
range = newRange;
|
||||
data->RenderObject->Range = newRange;
|
||||
LightNativeBridge.UpdateRange(data->RenderObject);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateFlags(AxLightFlags newFlags)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && flags != newFlags)
|
||||
{
|
||||
flags = newFlags;
|
||||
data->RenderObject->Flags = newFlags;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateAngles(float newLightAngle, float newFalloffAngle)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && (lightAngle != newLightAngle || falloffAngle != newFalloffAngle))
|
||||
{
|
||||
lightAngle = newLightAngle;
|
||||
falloffAngle = newFalloffAngle;
|
||||
data->RenderObject->LightAngle = newLightAngle;
|
||||
data->RenderObject->FalloffAngle = newFalloffAngle;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateFalloff(AxFalloffType newFalloffType, float newFalloffPower)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && (falloffType != newFalloffType || falloffPower != newFalloffPower))
|
||||
{
|
||||
falloffType = newFalloffType;
|
||||
falloffPower = newFalloffPower;
|
||||
data->RenderObject->FalloffType = newFalloffType;
|
||||
data->RenderObject->Falloff = newFalloffPower;
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void UpdateShadow(float newShadowNear, float newShadowFar, float newCharaShadowRange)
|
||||
{
|
||||
if (data != null && data->RenderObject != null && (shadowNear != newShadowNear || shadowFar != newShadowFar || charaShadowRange != newCharaShadowRange))
|
||||
{
|
||||
shadowNear = newShadowNear;
|
||||
shadowFar = newShadowFar;
|
||||
charaShadowRange = newCharaShadowRange;
|
||||
data->RenderObject->ShadowPlaneNear = newShadowNear;
|
||||
data->RenderObject->ShadowPlaneFar = newShadowFar;
|
||||
data->RenderObject->CharacterShadowRange = newCharaShadowRange;
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe void Tick()
|
||||
{
|
||||
if (data != null)
|
||||
{
|
||||
LightNativeBridge.UpdateCulling(data);
|
||||
LightNativeBridge.UpdateMaterial(data);
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void Dispose()
|
||||
{
|
||||
if (data != null)
|
||||
{
|
||||
GameLightVTable* virtualTable = data->VirtualTable;
|
||||
if (virtualTable != null)
|
||||
{
|
||||
virtualTable->Cleanup(data);
|
||||
virtualTable->Destructor(data, false);
|
||||
}
|
||||
data = null;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue