Minor cleanup.

This commit is contained in:
Ottermandias 2024-08-09 01:15:05 +02:00
parent b3d841a8ec
commit a52a43bd86
4 changed files with 38 additions and 55 deletions

View file

@ -11,10 +11,8 @@ public unsafe class HumanSetupScalingHook : FastHook<HumanSetupScalingHook.Deleg
public event EventDelegate? SetupReplacements; public event EventDelegate? SetupReplacements;
public HumanSetupScalingHook(HookManager hooks, CharacterBaseVTables vTables) 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); !HookOverrides.Instance.PostProcessing.HumanSetupScaling);
}
private void Detour(CharacterBase* drawObject, uint slotIndex) private void Detour(CharacterBase* drawObject, uint slotIndex)
{ {
@ -32,6 +30,7 @@ public unsafe class HumanSetupScalingHook : FastHook<HumanSetupScalingHook.Deleg
Monitor.Enter(shpkLock); Monitor.Enter(shpkLock);
releaseLock = true; releaseLock = true;
} }
for (var i = 0; i < numReplacements; ++i) for (var i = 0; i < numReplacements; ++i)
*(nint*)replacements[i].AddressToReplace = replacements[i].ValueToSet; *(nint*)replacements[i].AddressToReplace = replacements[i].ValueToSet;
Task.Result.Original(drawObject, slotIndex); Task.Result.Original(drawObject, slotIndex);

View file

@ -37,7 +37,7 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
_resourceLoader = resourceLoader; _resourceLoader = resourceLoader;
_framework = framework; _framework = framework;
_humanSetupScalingHook = humanSetupScalingHook; _humanSetupScalingHook = humanSetupScalingHook;
_humanSetupScalingHook.SetupReplacements += SetupHSSReplacements; _humanSetupScalingHook.SetupReplacements += SetupHssReplacements;
_humanCreateDeformerHook = hooks.CreateHook<CharacterBaseCreateDeformerDelegate>("HumanCreateDeformer", vTables.HumanVTable[101], _humanCreateDeformerHook = hooks.CreateHook<CharacterBaseCreateDeformerDelegate>("HumanCreateDeformer", vTables.HumanVTable[101],
CreateDeformer, !HookOverrides.Instance.PostProcessing.HumanCreateDeformer).Result; CreateDeformer, !HookOverrides.Instance.PostProcessing.HumanCreateDeformer).Result;
} }
@ -45,7 +45,7 @@ public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredServi
public void Dispose() public void Dispose()
{ {
_humanCreateDeformerHook.Dispose(); _humanCreateDeformerHook.Dispose();
_humanSetupScalingHook.SetupReplacements -= SetupHSSReplacements; _humanSetupScalingHook.SetupReplacements -= SetupHssReplacements;
} }
private SafeResourceHandle GetPreBoneDeformerForCharacter(CharacterBase* drawObject) 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); 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) ref int numReplacements, ref IDisposable? pbdDisposable, ref object? shpkLock)
{ {
if (!_framework.IsInFrameworkUpdateThread) if (!_framework.IsInFrameworkUpdateThread)
Penumbra.Log.Warning( 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); var preBoneDeformer = GetPreBoneDeformerForCharacter(drawObject);
try try
{ {
pbdDisposable = preBoneDeformer; 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); _utility.DefaultHumanPbdResource);
} }
catch catch

View file

@ -8,7 +8,6 @@ using OtterGui.Services;
using Penumbra.Communication; using Penumbra.Communication;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.Interop.Hooks.Resources; using Penumbra.Interop.Hooks.Resources;
using Penumbra.Interop.Services;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Services; using Penumbra.Services;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility; using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
@ -137,7 +136,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
_hairMaskState = _hairMaskState =
new ModdedShaderPackageState(() => _modelRenderer.HairMaskShaderPackage, () => _modelRenderer.DefaultHairMaskShaderPackage); new ModdedShaderPackageState(() => _modelRenderer.HairMaskShaderPackage, () => _modelRenderer.DefaultHairMaskShaderPackage);
_humanSetupScalingHook.SetupReplacements += SetupHSSReplacements; _humanSetupScalingHook.SetupReplacements += SetupHssReplacements;
_humanOnRenderMaterialHook = hooks.CreateHook<CharacterBaseOnRenderMaterialDelegate>("Human.OnRenderMaterial", vTables.HumanVTable[64], _humanOnRenderMaterialHook = hooks.CreateHook<CharacterBaseOnRenderMaterialDelegate>("Human.OnRenderMaterial", vTables.HumanVTable[64],
OnRenderHumanMaterial, !HookOverrides.Instance.PostProcessing.HumanOnRenderMaterial).Result; OnRenderHumanMaterial, !HookOverrides.Instance.PostProcessing.HumanOnRenderMaterial).Result;
_modelRendererOnRenderMaterialHook = hooks.CreateHook<ModelRendererOnRenderMaterialDelegate>("ModelRenderer.OnRenderMaterial", _modelRendererOnRenderMaterialHook = hooks.CreateHook<ModelRendererOnRenderMaterialDelegate>("ModelRenderer.OnRenderMaterial",
@ -146,7 +145,8 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
_modelRendererUnkFuncHook = hooks.CreateHook<ModelRendererUnkFuncDelegate>("ModelRenderer.UnkFunc", _modelRendererUnkFuncHook = hooks.CreateHook<ModelRendererUnkFuncDelegate>("ModelRenderer.UnkFunc",
Sigs.ModelRendererUnkFunc, ModelRendererUnkFuncDetour, Sigs.ModelRendererUnkFunc, ModelRendererUnkFuncDetour,
!HookOverrides.Instance.PostProcessing.ModelRendererUnkFunc).Result; !HookOverrides.Instance.PostProcessing.ModelRendererUnkFunc).Result;
_prepareColorTableHook = hooks.CreateHook<MaterialResourceHandle.Delegates.PrepareColorTable>("MaterialResourceHandle.PrepareColorTable", _prepareColorTableHook = hooks.CreateHook<MaterialResourceHandle.Delegates.PrepareColorTable>(
"MaterialResourceHandle.PrepareColorTable",
Sigs.PrepareColorSet, PrepareColorTableDetour, Sigs.PrepareColorSet, PrepareColorTableDetour,
!HookOverrides.Instance.PostProcessing.PrepareColorTable).Result; !HookOverrides.Instance.PostProcessing.PrepareColorTable).Result;
@ -160,7 +160,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
_modelRendererUnkFuncHook.Dispose(); _modelRendererUnkFuncHook.Dispose();
_modelRendererOnRenderMaterialHook.Dispose(); _modelRendererOnRenderMaterialHook.Dispose();
_humanOnRenderMaterialHook.Dispose(); _humanOnRenderMaterialHook.Dispose();
_humanSetupScalingHook.SetupReplacements -= SetupHSSReplacements; _humanSetupScalingHook.SetupReplacements -= SetupHssReplacements;
_communicator.MtrlLoaded.Unsubscribe(OnMtrlLoaded); _communicator.MtrlLoaded.Unsubscribe(OnMtrlLoaded);
_resourceHandleDestructor.Unsubscribe(OnResourceHandleDestructor); _resourceHandleDestructor.Unsubscribe(OnResourceHandleDestructor);
@ -188,14 +188,6 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
_characterOcclusionState.GetAndResetSlowPathCallDelta(), _characterOcclusionState.GetAndResetSlowPathCallDelta(),
_hairMaskState.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) private void OnMtrlLoaded(nint mtrlResourceHandle, nint gameObject)
{ {
var mtrl = (MaterialResourceHandle*)mtrlResourceHandle; var mtrl = (MaterialResourceHandle*)mtrlResourceHandle;
@ -204,7 +196,9 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
return; return;
var shpkName = mtrl->ShpkNameSpan; var shpkName = mtrl->ShpkNameSpan;
var shpkState = GetStateForHumanSetup(shpkName) ?? GetStateForHumanRender(shpkName) ?? GetStateForModelRendererRender(shpkName) var shpkState = GetStateForHumanSetup(shpkName)
?? GetStateForHumanRender(shpkName)
?? GetStateForModelRendererRender(shpkName)
?? GetStateForModelRendererUnk(shpkName) ?? GetStateForColorTable(shpkName); ?? GetStateForModelRendererUnk(shpkName) ?? GetStateForColorTable(shpkName);
if (shpkState != null && shpk != shpkState.DefaultShaderPackage) if (shpkState != null && shpk != shpkState.DefaultShaderPackage)
@ -228,12 +222,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
=> mtrlResource == null ? null : GetStateForHumanSetup(mtrlResource->ShpkNameSpan); => mtrlResource == null ? null : GetStateForHumanSetup(mtrlResource->ShpkNameSpan);
private ModdedShaderPackageState? GetStateForHumanSetup(ReadOnlySpan<byte> shpkName) private ModdedShaderPackageState? GetStateForHumanSetup(ReadOnlySpan<byte> shpkName)
{ => CharacterStockingsShpkName.SequenceEqual(shpkName) ? _characterStockingsState : null;
if (CharacterStockingsShpkName.SequenceEqual(shpkName))
return _characterStockingsState;
return null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private uint GetTotalMaterialCountForHumanSetup() private uint GetTotalMaterialCountForHumanSetup()
@ -243,12 +232,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
=> mtrlResource == null ? null : GetStateForHumanRender(mtrlResource->ShpkNameSpan); => mtrlResource == null ? null : GetStateForHumanRender(mtrlResource->ShpkNameSpan);
private ModdedShaderPackageState? GetStateForHumanRender(ReadOnlySpan<byte> shpkName) private ModdedShaderPackageState? GetStateForHumanRender(ReadOnlySpan<byte> shpkName)
{ => SkinShpkName.SequenceEqual(shpkName) ? _skinState : null;
if (SkinShpkName.SequenceEqual(shpkName))
return _skinState;
return null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private uint GetTotalMaterialCountForHumanRender() private uint GetTotalMaterialCountForHumanRender()
@ -305,18 +289,13 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
+ _characterStockingsState.MaterialCount; + _characterStockingsState.MaterialCount;
private ModdedShaderPackageState? GetStateForColorTable(ReadOnlySpan<byte> shpkName) private ModdedShaderPackageState? GetStateForColorTable(ReadOnlySpan<byte> shpkName)
{ => CharacterLegacyShpkName.SequenceEqual(shpkName) ? _characterLegacyState : null;
if (CharacterLegacyShpkName.SequenceEqual(shpkName))
return _characterLegacyState;
return null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private uint GetTotalMaterialCountForColorTable() private uint GetTotalMaterialCountForColorTable()
=> _characterLegacyState.MaterialCount; => _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) 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. // 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]; var model = drawObject->Models[slotIndex];
if (model == null) if (model == null)
return; return;
MaterialResourceHandle* mtrlResource = null; MaterialResourceHandle* mtrlResource = null;
ModdedShaderPackageState? shpkState = null; ModdedShaderPackageState? shpkState = null;
foreach (var material in model->MaterialsSpan) foreach (var material in model->MaterialsSpan)
@ -340,6 +320,7 @@ public sealed unsafe class ShaderReplacementFixer : IDisposable, IRequiredServic
if (shpkState != null) if (shpkState != null)
break; break;
} }
if (shpkState == null || shpkState.MaterialCount == 0) if (shpkState == null || shpkState.MaterialCount == 0)
return; 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. // 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. // There are still thread safety concerns as it might be called in other threads by plugins.
shpkLock = shpkState; 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); (nint)shpkState.DefaultShaderPackage);
} }
@ -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 // TODO ClientStructs-ify
var unkPointer = *(nint*)((nint)unkPayload->ModelResourceHandle + 0xE8) + unkPayload->UnkIndex * 0x24; 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) 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; return null;
} }
if (mtrlResource->ShaderPackageResourceHandle->ShaderPackage != unkPayload->ShaderWrapper->ShaderPackage) 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; return null;
} }

View file

@ -67,7 +67,7 @@ public unsafe class CharacterUtility : IDisposable, IRequiredService
_framework.Update += LoadDefaultResources; _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 _) private void LoadDefaultResources(object _)
{ {
if (Address == null) if (Address == null)