diff --git a/Penumbra.GameData b/Penumbra.GameData
index c855c17c..07d18f7f 160000
--- a/Penumbra.GameData
+++ b/Penumbra.GameData
@@ -1 +1 @@
-Subproject commit c855c17cffd7d270c3f013e01767cd052c24c462
+Subproject commit 07d18f7f7218811956e6663592e53c4145f2d862
diff --git a/Penumbra/Interop/Hooks/HookSettings.cs b/Penumbra/Interop/Hooks/HookSettings.cs
index a1dd374f..3deeb107 100644
--- a/Penumbra/Interop/Hooks/HookSettings.cs
+++ b/Penumbra/Interop/Hooks/HookSettings.cs
@@ -96,6 +96,7 @@ public class HookOverrides
public bool CheckFileState;
public bool TexResourceHandleOnLoad;
public bool LoadMdlFileExtern;
+ public bool SoundOnLoad;
}
public struct ResourceHooks
diff --git a/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs b/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs
index 9c17e0cf..b43f1ed5 100644
--- a/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs
+++ b/Penumbra/Interop/Hooks/ResourceLoading/TexMdlService.cs
@@ -7,6 +7,7 @@ using Penumbra.GameData;
using Penumbra.Interop.Structs;
using Penumbra.String.Classes;
using ResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle;
+using TextureResourceHandle = Penumbra.Interop.Structs.TextureResourceHandle;
namespace Penumbra.Interop.Hooks.ResourceLoading;
@@ -52,7 +53,8 @@ public unsafe class TexMdlScdService : IDisposable, IRequiredService
_loadMdlFileExternHook.Enable();
if (!HookOverrides.Instance.ResourceLoading.TexResourceHandleOnLoad)
_textureOnLoadHook.Enable();
- _soundOnLoadHook.Enable();
+ if (!HookOverrides.Instance.ResourceLoading.SoundOnLoad)
+ _soundOnLoadHook.Enable();
}
/// Add CRC64 if the given file is a model or texture file and has an associated path.
@@ -80,6 +82,7 @@ public unsafe class TexMdlScdService : IDisposable, IRequiredService
/// i.e. CRC32 of filename in the lower bytes, CRC32 of parent path in the upper bytes.
///
private readonly Dictionary _customFileCrc = [];
+
public IReadOnlyDictionary CustomCache
=> _customFileCrc;
@@ -98,15 +101,31 @@ public unsafe class TexMdlScdService : IDisposable, IRequiredService
private delegate byte SoundOnLoadDelegate(ResourceHandle* handle, SeFileDescriptor* descriptor, byte unk);
- [Signature("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 8B 79 ?? 48 8B DA 8B D7")]
+ [Signature(Sigs.LoadScdFileLocal)]
private readonly delegate* unmanaged _loadScdFileLocal = null!;
- [Signature("40 56 57 41 54 48 81 EC 90 00 00 00 80 3A 0B 45 0F B6 E0 48 8B F2", DetourName = nameof(OnScdLoadDetour))]
+ [Signature(Sigs.SoundOnLoad, DetourName = nameof(OnScdLoadDetour))]
private readonly Hook _soundOnLoadHook = null!;
+ [Signature(Sigs.RsfServiceAddress, ScanType = ScanType.StaticAddress)]
+ private readonly nint* _rsfService = null;
+
private byte OnScdLoadDetour(ResourceHandle* handle, SeFileDescriptor* descriptor, byte unk)
{
- var ret = _soundOnLoadHook.Original(handle, descriptor, unk);
+ byte ret;
+ if (*_rsfService == nint.Zero)
+ {
+ Penumbra.Log.Debug(
+ $"Resource load of {handle->FileName} before FFXIV RSF-service was instantiated, workaround by setting pointer.");
+ *_rsfService = 1;
+ ret = _soundOnLoadHook.Original(handle, descriptor, unk);
+ *_rsfService = nint.Zero;
+ }
+ else
+ {
+ ret = _soundOnLoadHook.Original(handle, descriptor, unk);
+ }
+
if (!_scdReturnData.Value)
return ret;