mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Minor cleanup.
This commit is contained in:
parent
b3d841a8ec
commit
a52a43bd86
4 changed files with 38 additions and 55 deletions
|
|
@ -11,10 +11,8 @@ public unsafe class HumanSetupScalingHook : FastHook<HumanSetupScalingHook.Deleg
|
|||
public event EventDelegate? SetupReplacements;
|
||||
|
||||
public HumanSetupScalingHook(HookManager hooks, CharacterBaseVTables vTables)
|
||||
{
|
||||
Task = hooks.CreateHook<Delegate>("Human.SetupScaling", vTables.HumanVTable[58], Detour,
|
||||
=> Task = hooks.CreateHook<Delegate>("Human.SetupScaling", vTables.HumanVTable[58], Detour,
|
||||
!HookOverrides.Instance.PostProcessing.HumanSetupScaling);
|
||||
}
|
||||
|
||||
private void Detour(CharacterBase* drawObject, uint slotIndex)
|
||||
{
|
||||
|
|
@ -32,6 +30,7 @@ public unsafe class HumanSetupScalingHook : FastHook<HumanSetupScalingHook.Deleg
|
|||
Monitor.Enter(shpkLock);
|
||||
releaseLock = true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < numReplacements; ++i)
|
||||
*(nint*)replacements[i].AddressToReplace = replacements[i].ValueToSet;
|
||||
Task.Result.Original(drawObject, slotIndex);
|
||||
|
|
@ -50,6 +49,6 @@ public unsafe class HumanSetupScalingHook : FastHook<HumanSetupScalingHook.Deleg
|
|||
|
||||
public delegate void EventDelegate(CharacterBase* drawObject, uint slotIndex, Span<Replacement> replacements, ref int numReplacements,
|
||||
ref IDisposable? pbdDisposable, ref object? shpkLock);
|
||||
|
||||
|
||||
public readonly record struct Replacement(nint AddressToReplace, nint ValueToSet, nint ValueToRestore);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
|
|||
Utf8GamePath.FromSpan("chara/xls/boneDeformer/human.pbd"u8, MetaDataComputation.All, out var p) ? p : Utf8GamePath.Empty;
|
||||
|
||||
// Approximate name guess.
|
||||
private delegate void* CharacterBaseCreateDeformerDelegate(CharacterBase* drawObject, uint slotIndex);
|
||||
private delegate void* CharacterBaseCreateDeformerDelegate(CharacterBase* drawObject, uint slotIndex);
|
||||
|
||||
private readonly Hook<CharacterBaseCreateDeformerDelegate> _humanCreateDeformerHook;
|
||||
|
||||
|
|
@ -32,12 +32,12 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
|
|||
public PreBoneDeformerReplacer(CharacterUtility utility, CollectionResolver collectionResolver, ResourceLoader resourceLoader,
|
||||
HookManager hooks, IFramework framework, CharacterBaseVTables vTables, HumanSetupScalingHook humanSetupScalingHook)
|
||||
{
|
||||
_utility = utility;
|
||||
_collectionResolver = collectionResolver;
|
||||
_resourceLoader = resourceLoader;
|
||||
_framework = framework;
|
||||
_humanSetupScalingHook = humanSetupScalingHook;
|
||||
_humanSetupScalingHook.SetupReplacements += SetupHSSReplacements;
|
||||
_utility = utility;
|
||||
_collectionResolver = collectionResolver;
|
||||
_resourceLoader = resourceLoader;
|
||||
_framework = framework;
|
||||
_humanSetupScalingHook = humanSetupScalingHook;
|
||||
_humanSetupScalingHook.SetupReplacements += SetupHssReplacements;
|
||||
_humanCreateDeformerHook = hooks.CreateHook<CharacterBaseCreateDeformerDelegate>("HumanCreateDeformer", vTables.HumanVTable[101],
|
||||
CreateDeformer, !HookOverrides.Instance.PostProcessing.HumanCreateDeformer).Result;
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
|
|||
public void Dispose()
|
||||
{
|
||||
_humanCreateDeformerHook.Dispose();
|
||||
_humanSetupScalingHook.SetupReplacements -= SetupHSSReplacements;
|
||||
_humanSetupScalingHook.SetupReplacements -= SetupHssReplacements;
|
||||
}
|
||||
|
||||
private SafeResourceHandle GetPreBoneDeformerForCharacter(CharacterBase* drawObject)
|
||||
|
|
@ -57,18 +57,19 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
|
|||
return cache.CustomResources.Get(ResourceCategory.Chara, ResourceType.Pbd, PreBoneDeformerPath, resolveData);
|
||||
}
|
||||
|
||||
private void SetupHSSReplacements(CharacterBase* drawObject, uint slotIndex, Span<HumanSetupScalingHook.Replacement> replacements,
|
||||
private void SetupHssReplacements(CharacterBase* drawObject, uint slotIndex, Span<HumanSetupScalingHook.Replacement> replacements,
|
||||
ref int numReplacements, ref IDisposable? pbdDisposable, ref object? shpkLock)
|
||||
{
|
||||
if (!_framework.IsInFrameworkUpdateThread)
|
||||
Penumbra.Log.Warning(
|
||||
$"{nameof(PreBoneDeformerReplacer)}.{nameof(SetupHSSReplacements)}(0x{(nint)drawObject:X}, {slotIndex}) called out of framework thread");
|
||||
$"{nameof(PreBoneDeformerReplacer)}.{nameof(SetupHssReplacements)}(0x{(nint)drawObject:X}, {slotIndex}) called out of framework thread");
|
||||
|
||||
var preBoneDeformer = GetPreBoneDeformerForCharacter(drawObject);
|
||||
try
|
||||
{
|
||||
pbdDisposable = preBoneDeformer;
|
||||
replacements[numReplacements++] = new((nint)(&_utility.Address->HumanPbdResource), (nint)preBoneDeformer.ResourceHandle,
|
||||
replacements[numReplacements++] = new HumanSetupScalingHook.Replacement((nint)(&_utility.Address->HumanPbdResource),
|
||||
(nint)preBoneDeformer.ResourceHandle,
|
||||
_utility.DefaultHumanPbdResource);
|
||||
}
|
||||
catch
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ using OtterGui.Services;
|
|||
using Penumbra.Communication;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.Interop.Hooks.Resources;
|
||||
using Penumbra.Interop.Services;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Services;
|
||||
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
|
||||
|
|
@ -137,7 +136,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
_hairMaskState =
|
||||
new ModdedShaderPackageState(() => _modelRenderer.HairMaskShaderPackage, () => _modelRenderer.DefaultHairMaskShaderPackage);
|
||||
|
||||
_humanSetupScalingHook.SetupReplacements += SetupHSSReplacements;
|
||||
_humanSetupScalingHook.SetupReplacements += SetupHssReplacements;
|
||||
_humanOnRenderMaterialHook = hooks.CreateHook<CharacterBaseOnRenderMaterialDelegate>("Human.OnRenderMaterial", vTables.HumanVTable[64],
|
||||
OnRenderHumanMaterial, !HookOverrides.Instance.PostProcessing.HumanOnRenderMaterial).Result;
|
||||
_modelRendererOnRenderMaterialHook = hooks.CreateHook<ModelRendererOnRenderMaterialDelegate>("ModelRenderer.OnRenderMaterial",
|
||||
|
|
@ -146,7 +145,8 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
_modelRendererUnkFuncHook = hooks.CreateHook<ModelRendererUnkFuncDelegate>("ModelRenderer.UnkFunc",
|
||||
Sigs.ModelRendererUnkFunc, ModelRendererUnkFuncDetour,
|
||||
!HookOverrides.Instance.PostProcessing.ModelRendererUnkFunc).Result;
|
||||
_prepareColorTableHook = hooks.CreateHook<MaterialResourceHandle.Delegates.PrepareColorTable>("MaterialResourceHandle.PrepareColorTable",
|
||||
_prepareColorTableHook = hooks.CreateHook<MaterialResourceHandle.Delegates.PrepareColorTable>(
|
||||
"MaterialResourceHandle.PrepareColorTable",
|
||||
Sigs.PrepareColorSet, PrepareColorTableDetour,
|
||||
!HookOverrides.Instance.PostProcessing.PrepareColorTable).Result;
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
_modelRendererUnkFuncHook.Dispose();
|
||||
_modelRendererOnRenderMaterialHook.Dispose();
|
||||
_humanOnRenderMaterialHook.Dispose();
|
||||
_humanSetupScalingHook.SetupReplacements -= SetupHSSReplacements;
|
||||
_humanSetupScalingHook.SetupReplacements -= SetupHssReplacements;
|
||||
|
||||
_communicator.MtrlLoaded.Unsubscribe(OnMtrlLoaded);
|
||||
_resourceHandleDestructor.Unsubscribe(OnResourceHandleDestructor);
|
||||
|
|
@ -188,14 +188,6 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
_characterOcclusionState.GetAndResetSlowPathCallDelta(),
|
||||
_hairMaskState.GetAndResetSlowPathCallDelta());
|
||||
|
||||
private static bool IsMaterialWithShpk(MaterialResourceHandle* mtrlResource, ReadOnlySpan<byte> shpkName)
|
||||
{
|
||||
if (mtrlResource == null)
|
||||
return false;
|
||||
|
||||
return shpkName.SequenceEqual(mtrlResource->ShpkNameSpan);
|
||||
}
|
||||
|
||||
private void OnMtrlLoaded(nint mtrlResourceHandle, nint gameObject)
|
||||
{
|
||||
var mtrl = (MaterialResourceHandle*)mtrlResourceHandle;
|
||||
|
|
@ -203,9 +195,11 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
if (shpk == null)
|
||||
return;
|
||||
|
||||
var shpkName = mtrl->ShpkNameSpan;
|
||||
var shpkState = GetStateForHumanSetup(shpkName) ?? GetStateForHumanRender(shpkName) ?? GetStateForModelRendererRender(shpkName)
|
||||
?? GetStateForModelRendererUnk(shpkName) ?? GetStateForColorTable(shpkName);
|
||||
var shpkName = mtrl->ShpkNameSpan;
|
||||
var shpkState = GetStateForHumanSetup(shpkName)
|
||||
?? GetStateForHumanRender(shpkName)
|
||||
?? GetStateForModelRendererRender(shpkName)
|
||||
?? GetStateForModelRendererUnk(shpkName) ?? GetStateForColorTable(shpkName);
|
||||
|
||||
if (shpkState != null && shpk != shpkState.DefaultShaderPackage)
|
||||
shpkState.TryAddMaterial(mtrlResourceHandle);
|
||||
|
|
@ -228,12 +222,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
=> mtrlResource == null ? null : GetStateForHumanSetup(mtrlResource->ShpkNameSpan);
|
||||
|
||||
private ModdedShaderPackageState? GetStateForHumanSetup(ReadOnlySpan<byte> shpkName)
|
||||
{
|
||||
if (CharacterStockingsShpkName.SequenceEqual(shpkName))
|
||||
return _characterStockingsState;
|
||||
|
||||
return null;
|
||||
}
|
||||
=> CharacterStockingsShpkName.SequenceEqual(shpkName) ? _characterStockingsState : null;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private uint GetTotalMaterialCountForHumanSetup()
|
||||
|
|
@ -243,12 +232,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
=> mtrlResource == null ? null : GetStateForHumanRender(mtrlResource->ShpkNameSpan);
|
||||
|
||||
private ModdedShaderPackageState? GetStateForHumanRender(ReadOnlySpan<byte> shpkName)
|
||||
{
|
||||
if (SkinShpkName.SequenceEqual(shpkName))
|
||||
return _skinState;
|
||||
|
||||
return null;
|
||||
}
|
||||
=> SkinShpkName.SequenceEqual(shpkName) ? _skinState : null;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private uint GetTotalMaterialCountForHumanRender()
|
||||
|
|
@ -305,18 +289,13 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
+ _characterStockingsState.MaterialCount;
|
||||
|
||||
private ModdedShaderPackageState? GetStateForColorTable(ReadOnlySpan<byte> shpkName)
|
||||
{
|
||||
if (CharacterLegacyShpkName.SequenceEqual(shpkName))
|
||||
return _characterLegacyState;
|
||||
|
||||
return null;
|
||||
}
|
||||
=> CharacterLegacyShpkName.SequenceEqual(shpkName) ? _characterLegacyState : null;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||
private uint GetTotalMaterialCountForColorTable()
|
||||
=> _characterLegacyState.MaterialCount;
|
||||
|
||||
private void SetupHSSReplacements(CharacterBase* drawObject, uint slotIndex, Span<HumanSetupScalingHook.Replacement> replacements,
|
||||
private void SetupHssReplacements(CharacterBase* drawObject, uint slotIndex, Span<HumanSetupScalingHook.Replacement> replacements,
|
||||
ref int numReplacements, ref IDisposable? pbdDisposable, ref object? shpkLock)
|
||||
{
|
||||
// If we don't have any on-screen instances of modded characterstockings.shpk, we don't need the slow path at all.
|
||||
|
|
@ -326,6 +305,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
var model = drawObject->Models[slotIndex];
|
||||
if (model == null)
|
||||
return;
|
||||
|
||||
MaterialResourceHandle* mtrlResource = null;
|
||||
ModdedShaderPackageState? shpkState = null;
|
||||
foreach (var material in model->MaterialsSpan)
|
||||
|
|
@ -340,6 +320,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
if (shpkState != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (shpkState == null || shpkState.MaterialCount == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -348,7 +329,8 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
// This is less performance-critical than the others, as this is called by the game only on draw object creation and slot update.
|
||||
// There are still thread safety concerns as it might be called in other threads by plugins.
|
||||
shpkLock = shpkState;
|
||||
replacements[numReplacements++] = new((nint)shpkState.ShaderPackageReference, (nint)mtrlResource->ShaderPackageResourceHandle,
|
||||
replacements[numReplacements++] = new HumanSetupScalingHook.Replacement((nint)shpkState.ShaderPackageReference,
|
||||
(nint)mtrlResource->ShaderPackageResourceHandle,
|
||||
(nint)shpkState.DefaultShaderPackage);
|
||||
}
|
||||
|
||||
|
|
@ -439,7 +421,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
// Same performance considerations as OnRenderHumanMaterial.
|
||||
lock (shpkState)
|
||||
{
|
||||
var shpkReference = shpkState.ShaderPackageReference;
|
||||
var shpkReference = shpkState.ShaderPackageReference;
|
||||
try
|
||||
{
|
||||
*shpkReference = mtrlResource->ShaderPackageResourceHandle;
|
||||
|
|
@ -452,7 +434,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
}
|
||||
}
|
||||
|
||||
private MaterialResourceHandle* GetMaterialResourceHandle(ModelRendererStructs.UnkPayload* unkPayload)
|
||||
private static MaterialResourceHandle* GetMaterialResourceHandle(ModelRendererStructs.UnkPayload* unkPayload)
|
||||
{
|
||||
// TODO ClientStructs-ify
|
||||
var unkPointer = *(nint*)((nint)unkPayload->ModelResourceHandle + 0xE8) + unkPayload->UnkIndex * 0x24;
|
||||
|
|
@ -467,13 +449,14 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
|
|||
|
||||
if (mtrlResource->ShaderPackageResourceHandle == null)
|
||||
{
|
||||
Penumbra.Log.Warning($"ShaderReplacementFixer found a MaterialResourceHandle with no shader package");
|
||||
Penumbra.Log.Warning("ShaderReplacementFixer found a MaterialResourceHandle with no shader package");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mtrlResource->ShaderPackageResourceHandle->ShaderPackage != unkPayload->ShaderWrapper->ShaderPackage)
|
||||
{
|
||||
Penumbra.Log.Warning($"ShaderReplacementFixer found a MaterialResourceHandle (0x{(nint)mtrlResource:X}) with an inconsistent shader package (got 0x{(nint)mtrlResource->ShaderPackageResourceHandle->ShaderPackage:X}, expected 0x{(nint)unkPayload->ShaderWrapper->ShaderPackage:X})");
|
||||
Penumbra.Log.Warning(
|
||||
$"ShaderReplacementFixer found a MaterialResourceHandle (0x{(nint)mtrlResource:X}) with an inconsistent shader package (got 0x{(nint)mtrlResource->ShaderPackageResourceHandle->ShaderPackage:X}, expected 0x{(nint)unkPayload->ShaderWrapper->ShaderPackage:X})");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public unsafe class CharacterUtility : IDisposable, IRequiredService
|
|||
_framework.Update += LoadDefaultResources;
|
||||
}
|
||||
|
||||
/// <summary> We store the default data of the resources so we can always restore them. </summary>
|
||||
/// <summary> We store the default data of the resources, so we can always restore them. </summary>
|
||||
private void LoadDefaultResources(object _)
|
||||
{
|
||||
if (Address == null)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue