Add a hook for updating looped scds.

This commit is contained in:
Ottermandias 2023-01-06 14:34:28 +01:00
parent baf3b06060
commit 72408bf45c
3 changed files with 58 additions and 25 deletions

@ -1 +1 @@
Subproject commit 6a1e25a6c6aea6165c0a38771953e35550a1f9cf
Subproject commit 7c7b641feb30c1a03c47a5653c7f7cdde529dfc7

View file

@ -70,6 +70,7 @@ public unsafe partial class PathResolver
_loadCharacterSoundHook.Enable();
_loadCharacterVfxHook.Enable();
_loadAreaVfxHook.Enable();
_scheduleClipUpdateHook.Enable();
//_loadSomeAvfxHook.Enable();
//_someOtherAvfxHook.Enable();
@ -84,6 +85,7 @@ public unsafe partial class PathResolver
_loadCharacterSoundHook.Disable();
_loadCharacterVfxHook.Disable();
_loadAreaVfxHook.Disable();
_scheduleClipUpdateHook.Disable();
//_loadSomeAvfxHook.Disable();
//_someOtherAvfxHook.Disable();
@ -98,6 +100,7 @@ public unsafe partial class PathResolver
_loadCharacterSoundHook.Dispose();
_loadCharacterVfxHook.Dispose();
_loadAreaVfxHook.Dispose();
_scheduleClipUpdateHook.Dispose();
//_loadSomeAvfxHook.Dispose();
//_someOtherAvfxHook.Dispose();
@ -119,6 +122,29 @@ public unsafe partial class PathResolver
return ret;
}
private static ResolveData GetDataFromTimeline( IntPtr timeline )
{
try
{
if( timeline != IntPtr.Zero )
{
var getGameObjectIdx = ( ( delegate* unmanaged< IntPtr, int >** )timeline )[ 0 ][ 28 ];
var idx = getGameObjectIdx( timeline );
if( idx >= 0 && idx < Dalamud.Objects.Length )
{
var obj = Dalamud.Objects[ idx ];
return obj != null ? IdentifyCollection( ( GameObject* )obj.Address, true ) : ResolveData.Invalid;
}
}
}
catch( Exception e )
{
Penumbra.Log.Error( $"Error getting timeline data for 0x{timeline:X}:\n{e}" );
}
return ResolveData.Invalid;
}
// The timeline object loads the requested .tmb and .pap files. The .tmb files load the respective .avfx files.
// We can obtain the associated game object from the timelines 28'th vfunc and use that to apply the correct collection.
private delegate ulong LoadTimelineResourcesDelegate( IntPtr timeline );
@ -129,30 +155,9 @@ public unsafe partial class PathResolver
private ulong LoadTimelineResourcesDetour( IntPtr timeline )
{
using var performance = Penumbra.Performance.Measure( PerformanceType.TimelineResources );
ulong ret;
var old = _animationLoadData;
try
{
if( timeline != IntPtr.Zero )
{
var getGameObjectIdx = ( ( delegate* unmanaged< IntPtr, int >** )timeline )[ 0 ][ 28 ];
var idx = getGameObjectIdx( timeline );
if( idx >= 0 && idx < Dalamud.Objects.Length )
{
var obj = Dalamud.Objects[ idx ];
_animationLoadData = obj != null ? IdentifyCollection( ( GameObject* )obj.Address, true ) : ResolveData.Invalid;
}
else
{
_animationLoadData = ResolveData.Invalid;
}
}
}
finally
{
ret = _loadTimelineResourcesHook.Original( timeline );
}
var old = _animationLoadData;
_animationLoadData = GetDataFromTimeline( timeline );
var ret = _loadTimelineResourcesHook.Original( timeline );
_animationLoadData = old;
return ret;
}
@ -309,6 +314,32 @@ public unsafe partial class PathResolver
}
[StructLayout( LayoutKind.Explicit )]
private struct ClipScheduler
{
[FieldOffset( 0 )]
public IntPtr* VTable;
[FieldOffset( 0x38 )]
public IntPtr SchedulerTimeline;
}
private delegate void ScheduleClipUpdate( ClipScheduler* x );
[Signature( "40 53 55 56 57 41 56 48 81 EC ?? ?? ?? ?? 48 8B F9", DetourName = nameof( ScheduleClipUpdateDetour ) )]
private readonly Hook< ScheduleClipUpdate > _scheduleClipUpdateHook = null!;
private void ScheduleClipUpdateDetour( ClipScheduler* x )
{
using var performance = Penumbra.Performance.Measure( PerformanceType.ScheduleClipUpdate );
var old = _animationLoadData;
var timeline = x->SchedulerTimeline;
_animationLoadData = GetDataFromTimeline( timeline );
_scheduleClipUpdateHook.Original( x );
_animationLoadData = old;
}
// ========== Those hooks seem to be superseded by LoadCharacterVfx =========
// public delegate ulong LoadSomeAvfx( uint a1, IntPtr gameObject, IntPtr gameObject2, float unk1, IntPtr unk2, IntPtr unk3 );

View file

@ -13,6 +13,7 @@ public enum PerformanceType
LoadCharacterVfx,
LoadAreaVfx,
LoadSound,
ScheduleClipUpdate,
LoadAction,
LoadCharacterBaseAnimation,
LoadPap,
@ -51,6 +52,7 @@ public static class PerformanceTypeExtensions
PerformanceType.SetupCharacter => "SetupCharacter Hook",
PerformanceType.ChangeCustomize => "ChangeCustomize Hook",
PerformanceType.LoadSound => "LoadSound Hook",
PerformanceType.ScheduleClipUpdate => "ScheduleClipUpdate Hook",
PerformanceType.LoadCharacterBaseAnimation => "LoadCharacterAnimation Hook",
PerformanceType.LoadPap => "LoadPap Hook",
PerformanceType.LoadAction => "LoadAction Hook",