diff --git a/Penumbra/Interop/PathResolving/PathState.cs b/Penumbra/Interop/PathResolving/PathState.cs index 4fb3d31d..f300a666 100644 --- a/Penumbra/Interop/PathResolving/PathState.cs +++ b/Penumbra/Interop/PathResolving/PathState.cs @@ -42,7 +42,7 @@ public unsafe class PathState : IDisposable MetaState = metaState; CharacterUtility = characterUtility; _human = new ResolvePathHooks(interop, this, _humanVTable, ResolvePathHooks.Type.Human); - _weapon = new ResolvePathHooks(interop, this, _weaponVTable, ResolvePathHooks.Type.Weapon); + _weapon = new ResolvePathHooks(interop, this, _weaponVTable, ResolvePathHooks.Type.Other); _demiHuman = new ResolvePathHooks(interop, this, _demiHumanVTable, ResolvePathHooks.Type.Other); _monster = new ResolvePathHooks(interop, this, _monsterVTable, ResolvePathHooks.Type.Other); _human.Enable(); diff --git a/Penumbra/Interop/PathResolving/ResolvePathHooks.cs b/Penumbra/Interop/PathResolving/ResolvePathHooks.cs index f9a341b9..9d010d64 100644 --- a/Penumbra/Interop/PathResolving/ResolvePathHooks.cs +++ b/Penumbra/Interop/PathResolving/ResolvePathHooks.cs @@ -12,45 +12,47 @@ public unsafe class ResolvePathHooks : IDisposable public enum Type { Human, - Weapon, Other, } - private delegate nint GeneralResolveDelegate(nint drawObject, nint path, nint unk3, uint unk4); - private delegate nint MPapResolveDelegate(nint drawObject, nint path, nint unk3, uint unk4, uint unk5); - private delegate nint MaterialResolveDelegate(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5); - private delegate nint EidResolveDelegate(nint drawObject, nint path, nint unk3); + private delegate nint MPapResolveDelegate(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex, uint sId); + private delegate nint NamedResolveDelegate(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex, nint name); + private delegate nint PerSlotResolveDelegate(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex); + private delegate nint SingleResolveDelegate(nint drawObject, nint pathBuffer, nint pathBufferSize); + private delegate nint TmbResolveDelegate(nint drawObject, nint pathBuffer, nint pathBufferSize, nint timelineName); + // Kept separate from NamedResolveDelegate because the 5th parameter has out semantics here, instead of in. + private delegate nint VfxResolveDelegate(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex, nint unkOutParam); - private readonly Hook _resolveDecalPathHook; - private readonly Hook _resolveEidPathHook; - private readonly Hook _resolveImcPathHook; - private readonly Hook _resolveMPapPathHook; - private readonly Hook _resolveMdlPathHook; - private readonly Hook _resolveMtrlPathHook; - private readonly Hook _resolvePapPathHook; - private readonly Hook _resolvePhybPathHook; - private readonly Hook _resolveSklbPathHook; - private readonly Hook _resolveSkpPathHook; - private readonly Hook _resolveTmbPathHook; - private readonly Hook _resolveVfxPathHook; + private readonly Hook _resolveDecalPathHook; + private readonly Hook _resolveEidPathHook; + private readonly Hook _resolveImcPathHook; + private readonly Hook _resolveMPapPathHook; + private readonly Hook _resolveMdlPathHook; + private readonly Hook _resolveMtrlPathHook; + private readonly Hook _resolvePapPathHook; + private readonly Hook _resolvePhybPathHook; + private readonly Hook _resolveSklbPathHook; + private readonly Hook _resolveSkpPathHook; + private readonly Hook _resolveTmbPathHook; + private readonly Hook _resolveVfxPathHook; private readonly PathState _parent; public ResolvePathHooks(IGameInteropProvider interop, PathState parent, nint* vTable, Type type) { _parent = parent; - _resolveDecalPathHook = Create(interop, vTable[83], type, ResolveDecalWeapon, ResolveDecal); - _resolveEidPathHook = Create(interop, vTable[85], type, ResolveEidWeapon, ResolveEid); - _resolveImcPathHook = Create(interop, vTable[81], type, ResolveImcWeapon, ResolveImc); - _resolveMPapPathHook = Create(interop, vTable[79], type, ResolveMPapWeapon, ResolveMPap); - _resolveMdlPathHook = Create(interop, vTable[73], type, ResolveMdlWeapon, ResolveMdl, ResolveMdlHuman); - _resolveMtrlPathHook = Create(interop, vTable[82], type, ResolveMtrlWeapon, ResolveMtrl); - _resolvePapPathHook = Create(interop, vTable[76], type, ResolvePapWeapon, ResolvePap, ResolvePapHuman); - _resolvePhybPathHook = Create(interop, vTable[75], type, ResolvePhybWeapon, ResolvePhyb, ResolvePhybHuman); - _resolveSklbPathHook = Create(interop, vTable[72], type, ResolveSklbWeapon, ResolveSklb, ResolveSklbHuman); - _resolveSkpPathHook = Create(interop, vTable[74], type, ResolveSkpWeapon, ResolveSkp, ResolveSkpHuman); - _resolveTmbPathHook = Create(interop, vTable[77], type, ResolveTmbWeapon, ResolveTmb); - _resolveVfxPathHook = Create(interop, vTable[84], type, ResolveVfxWeapon, ResolveVfx); + _resolveDecalPathHook = Create(interop, vTable[83], ResolveDecal); + _resolveEidPathHook = Create(interop, vTable[85], ResolveEid); + _resolveImcPathHook = Create(interop, vTable[81], ResolveImc); + _resolveMPapPathHook = Create(interop, vTable[79], ResolveMPap); + _resolveMdlPathHook = Create(interop, vTable[73], type, ResolveMdl, ResolveMdlHuman); + _resolveMtrlPathHook = Create(interop, vTable[82], ResolveMtrl); + _resolvePapPathHook = Create(interop, vTable[76], type, ResolvePap, ResolvePapHuman); + _resolvePhybPathHook = Create(interop, vTable[75], type, ResolvePhyb, ResolvePhybHuman); + _resolveSklbPathHook = Create(interop, vTable[72], type, ResolveSklb, ResolveSklbHuman); + _resolveSkpPathHook = Create(interop, vTable[74], type, ResolveSkp, ResolveSkpHuman); + _resolveTmbPathHook = Create(interop, vTable[77], ResolveTmb); + _resolveVfxPathHook = Create(interop, vTable[84], ResolveVfx); } public void Enable() @@ -101,74 +103,74 @@ public unsafe class ResolvePathHooks : IDisposable _resolveVfxPathHook.Dispose(); } - private nint ResolveDecal(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveDecalPathHook.Original(drawObject, path, unk3, unk4)); + private nint ResolveDecal(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex) + => ResolvePath(drawObject, _resolveDecalPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex)); - private nint ResolveEid(nint drawObject, nint path, nint unk3) - => ResolvePath(drawObject, _resolveEidPathHook.Original(drawObject, path, unk3)); + private nint ResolveEid(nint drawObject, nint pathBuffer, nint pathBufferSize) + => ResolvePath(drawObject, _resolveEidPathHook.Original(drawObject, pathBuffer, pathBufferSize)); - private nint ResolveImc(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveImcPathHook.Original(drawObject, path, unk3, unk4)); + private nint ResolveImc(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex) + => ResolvePath(drawObject, _resolveImcPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex)); - private nint ResolveMPap(nint drawObject, nint path, nint unk3, uint unk4, uint unk5) - => ResolvePath(drawObject, _resolveMPapPathHook.Original(drawObject, path, unk3, unk4, unk5)); + private nint ResolveMPap(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex, uint unkSId) + => ResolvePath(drawObject, _resolveMPapPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex, unkSId)); - private nint ResolveMdl(nint drawObject, nint path, nint unk3, uint modelType) - => ResolvePath(drawObject, _resolveMdlPathHook.Original(drawObject, path, unk3, modelType)); + private nint ResolveMdl(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex) + => ResolvePath(drawObject, _resolveMdlPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex)); - private nint ResolveMtrl(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5) - => ResolvePath(drawObject, _resolveMtrlPathHook.Original(drawObject, path, unk3, unk4, unk5)); + private nint ResolveMtrl(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex, nint mtrlFileName) + => ResolvePath(drawObject, _resolveMtrlPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex, mtrlFileName)); - private nint ResolvePap(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5) - => ResolvePath(drawObject, _resolvePapPathHook.Original(drawObject, path, unk3, unk4, unk5)); + private nint ResolvePap(nint drawObject, nint pathBuffer, nint pathBufferSize, uint unkAnimationIndex, nint animationName) + => ResolvePath(drawObject, _resolvePapPathHook.Original(drawObject, pathBuffer, pathBufferSize, unkAnimationIndex, animationName)); - private nint ResolvePhyb(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolvePhybPathHook.Original(drawObject, path, unk3, unk4)); + private nint ResolvePhyb(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex) + => ResolvePath(drawObject, _resolvePhybPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex)); - private nint ResolveSklb(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveSklbPathHook.Original(drawObject, path, unk3, unk4)); + private nint ResolveSklb(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex) + => ResolvePath(drawObject, _resolveSklbPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex)); - private nint ResolveSkp(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveSkpPathHook.Original(drawObject, path, unk3, unk4)); + private nint ResolveSkp(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex) + => ResolvePath(drawObject, _resolveSkpPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex)); - private nint ResolveTmb(nint drawObject, nint path, nint unk3) - => ResolvePath(drawObject, _resolveTmbPathHook.Original(drawObject, path, unk3)); + private nint ResolveTmb(nint drawObject, nint pathBuffer, nint pathBufferSize, nint timelineName) + => ResolvePath(drawObject, _resolveTmbPathHook.Original(drawObject, pathBuffer, pathBufferSize, timelineName)); - private nint ResolveVfx(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5) - => ResolvePath(drawObject, _resolveVfxPathHook.Original(drawObject, path, unk3, unk4, unk5)); + private nint ResolveVfx(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex, nint unkOutParam) + => ResolvePath(drawObject, _resolveVfxPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex, unkOutParam)); - private nint ResolveMdlHuman(nint drawObject, nint path, nint unk3, uint modelType) + private nint ResolveMdlHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex) { var data = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true); - using var eqdp = modelType > 9 + using var eqdp = slotIndex > 9 ? DisposableContainer.Empty - : _parent.MetaState.ResolveEqdpData(data.ModCollection, MetaState.GetHumanGenderRace(drawObject), modelType < 5, modelType > 4); - return ResolvePath(data, _resolveMdlPathHook.Original(drawObject, path, unk3, modelType)); + : _parent.MetaState.ResolveEqdpData(data.ModCollection, MetaState.GetHumanGenderRace(drawObject), slotIndex < 5, slotIndex > 4); + return ResolvePath(data, _resolveMdlPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex)); } - private nint ResolvePapHuman(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5) + private nint ResolvePapHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint unkAnimationIndex, nint animationName) { using var est = GetEstChanges(drawObject, out var data); - return ResolvePath(data, _resolvePapPathHook.Original(drawObject, path, unk3, unk4, unk5)); + return ResolvePath(data, _resolvePapPathHook.Original(drawObject, pathBuffer, pathBufferSize, unkAnimationIndex, animationName)); } - private nint ResolvePhybHuman(nint drawObject, nint path, nint unk3, uint unk4) + private nint ResolvePhybHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex) { using var est = GetEstChanges(drawObject, out var data); - return ResolvePath(data, _resolvePhybPathHook.Original(drawObject, path, unk3, unk4)); + return ResolvePath(data, _resolvePhybPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex)); } - private nint ResolveSklbHuman(nint drawObject, nint path, nint unk3, uint unk4) + private nint ResolveSklbHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex) { using var est = GetEstChanges(drawObject, out var data); - return ResolvePath(data, _resolveSklbPathHook.Original(drawObject, path, unk3, unk4)); + return ResolvePath(data, _resolveSklbPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex)); } - private nint ResolveSkpHuman(nint drawObject, nint path, nint unk3, uint unk4) + private nint ResolveSkpHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex) { using var est = GetEstChanges(drawObject, out var data); - return ResolvePath(data, _resolveSkpPathHook.Original(drawObject, path, unk3, unk4)); + return ResolvePath(data, _resolveSkpPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex)); } private DisposableContainer GetEstChanges(nint drawObject, out ResolveData data) @@ -180,58 +182,21 @@ public unsafe class ResolvePathHooks : IDisposable data.ModCollection.TemporarilySetEstFile(_parent.CharacterUtility, EstManipulation.EstType.Head)); } - private nint ResolveDecalWeapon(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveDecalPathHook.Original(drawObject, path, unk3, unk4)); - - private nint ResolveEidWeapon(nint drawObject, nint path, nint unk3) - => ResolvePath(drawObject, _resolveEidPathHook.Original(drawObject, path, unk3)); - - private nint ResolveImcWeapon(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveImcPathHook.Original(drawObject, path, unk3, unk4)); - - private nint ResolveMPapWeapon(nint drawObject, nint path, nint unk3, uint unk4, uint unk5) - => ResolvePath(drawObject, _resolveMPapPathHook.Original(drawObject, path, unk3, unk4, unk5)); - - private nint ResolveMdlWeapon(nint drawObject, nint path, nint unk3, uint modelType) - => ResolvePath(drawObject, _resolveMdlPathHook.Original(drawObject, path, unk3, modelType)); - - private nint ResolveMtrlWeapon(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5) - => ResolvePath(drawObject, _resolveMtrlPathHook.Original(drawObject, path, unk3, unk4, unk5)); - - private nint ResolvePapWeapon(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5) - => ResolvePath(drawObject, _resolvePapPathHook.Original(drawObject, path, unk3, unk4, unk5)); - - private nint ResolvePhybWeapon(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolvePhybPathHook.Original(drawObject, path, unk3, unk4)); - - private nint ResolveSklbWeapon(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveSklbPathHook.Original(drawObject, path, unk3, unk4)); - - private nint ResolveSkpWeapon(nint drawObject, nint path, nint unk3, uint unk4) - => ResolvePath(drawObject, _resolveSkpPathHook.Original(drawObject, path, unk3, unk4)); - - private nint ResolveTmbWeapon(nint drawObject, nint path, nint unk3) - => ResolvePath(drawObject, _resolveTmbPathHook.Original(drawObject, path, unk3)); - - private nint ResolveVfxWeapon(nint drawObject, nint path, nint unk3, uint unk4, ulong unk5) - => ResolvePath(drawObject, _resolveVfxPathHook.Original(drawObject, path, unk3, unk4, unk5)); - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - private static Hook Create(IGameInteropProvider interop, nint address, Type type, T weapon, T other, T human) where T : Delegate + private static Hook Create(IGameInteropProvider interop, nint address, Type type, T other, T human) where T : Delegate { var del = type switch { Type.Human => human, - Type.Weapon => weapon, _ => other, }; return interop.HookFromAddress(address, del); } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] - private static Hook Create(IGameInteropProvider interop, nint address, Type type, T weapon, T other) where T : Delegate - => Create(interop, address, type, weapon, other, other); + private static Hook Create(IGameInteropProvider interop, nint address, T del) where T : Delegate + => interop.HookFromAddress(address, del); // Implementation