mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Add a hook for updating looped scds.
This commit is contained in:
parent
baf3b06060
commit
72408bf45c
3 changed files with 58 additions and 25 deletions
2
OtterGui
2
OtterGui
|
|
@ -1 +1 @@
|
|||
Subproject commit 6a1e25a6c6aea6165c0a38771953e35550a1f9cf
|
||||
Subproject commit 7c7b641feb30c1a03c47a5653c7f7cdde529dfc7
|
||||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue