mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Fix handling of decals overall.
This commit is contained in:
parent
e3a608fe0e
commit
6e7805d58f
4 changed files with 32 additions and 15 deletions
|
|
@ -49,7 +49,7 @@ public unsafe class MetaState : IDisposable
|
|||
private readonly CommunicatorService _communicator;
|
||||
private readonly PerformanceTracker _performance;
|
||||
private readonly CollectionResolver _collectionResolver;
|
||||
private readonly ResourceService _resources;
|
||||
private readonly ResourceLoader _resources;
|
||||
private readonly GameEventManager _gameEventManager;
|
||||
private readonly CharacterUtility _characterUtility;
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ public unsafe class MetaState : IDisposable
|
|||
private DisposableContainer _characterBaseCreateMetaChanges = DisposableContainer.Empty;
|
||||
|
||||
public MetaState(PerformanceTracker performance, CommunicatorService communicator, CollectionResolver collectionResolver,
|
||||
ResourceService resources, GameEventManager gameEventManager, CharacterUtility characterUtility, Configuration config)
|
||||
ResourceLoader resources, GameEventManager gameEventManager, CharacterUtility characterUtility, Configuration config)
|
||||
{
|
||||
_performance = performance;
|
||||
_communicator = communicator;
|
||||
|
|
@ -129,7 +129,7 @@ public unsafe class MetaState : IDisposable
|
|||
_communicator.CreatingCharacterBase.Invoke(_lastCreatedCollection.AssociatedGameObject,
|
||||
_lastCreatedCollection.ModCollection.Name, (nint)(&modelCharaId), customize, equipData);
|
||||
|
||||
var decal = new DecalReverter(_config, _characterUtility, _resources, _lastCreatedCollection.ModCollection, UsesDecal(modelCharaId, customize));
|
||||
var decal = new DecalReverter(_config, _characterUtility, _resources, _lastCreatedCollection, UsesDecal(modelCharaId, customize));
|
||||
var cmp = _lastCreatedCollection.ModCollection.TemporarilySetCmpFile(_characterUtility);
|
||||
_characterBaseCreateMetaChanges.Dispose(); // Should always be empty.
|
||||
_characterBaseCreateMetaChanges = new DisposableContainer(decal, cmp);
|
||||
|
|
@ -255,9 +255,9 @@ public unsafe class MetaState : IDisposable
|
|||
_inChangeCustomize = true;
|
||||
var resolveData = _collectionResolver.IdentifyCollection((DrawObject*)human, true);
|
||||
using var cmp = resolveData.ModCollection.TemporarilySetCmpFile(_characterUtility);
|
||||
using var decals =
|
||||
new DecalReverter(_config, _characterUtility, _resources, resolveData.ModCollection, UsesDecal(0, data));
|
||||
var ret = _changeCustomize.Original(human, data, skipEquipment);
|
||||
using var decals = new DecalReverter(_config, _characterUtility, _resources, resolveData, true);
|
||||
using var decal2 = new DecalReverter(_config, _characterUtility, _resources, resolveData, false);
|
||||
var ret = _changeCustomize.Original(human, data, skipEquipment);
|
||||
_inChangeCustomize = false;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ public unsafe class ResourceLoader : IDisposable
|
|||
private readonly FileReadService _fileReadService;
|
||||
private readonly TexMdlService _texMdlService;
|
||||
|
||||
private ResolveData _resolvedData = ResolveData.Invalid;
|
||||
|
||||
public ResourceLoader(ResourceService resources, FileReadService fileReadService, TexMdlService texMdlService,
|
||||
CreateFileWHook _)
|
||||
{
|
||||
|
|
@ -30,6 +32,15 @@ public unsafe class ResourceLoader : IDisposable
|
|||
_fileReadService.ReadSqPack += ReadSqPackDetour;
|
||||
}
|
||||
|
||||
/// <summary> Load a resource for a given path and a specific collection. </summary>
|
||||
public ResourceHandle* LoadResolvedResource(ResourceCategory category, ResourceType type, ByteString path, ResolveData resolveData)
|
||||
{
|
||||
_resolvedData = resolveData;
|
||||
var ret = _resources.GetResource(category, type, path);
|
||||
_resolvedData = ResolveData.Invalid;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary> The function to use to resolve a given path. </summary>
|
||||
public Func<Utf8GamePath, ResourceCategory, ResourceType, (FullPath?, ResolveData)> ResolvePath = null!;
|
||||
|
||||
|
|
@ -66,7 +77,8 @@ public unsafe class ResourceLoader : IDisposable
|
|||
_fileReadService.ReadSqPack -= ReadSqPackDetour;
|
||||
}
|
||||
|
||||
private void ResourceHandler(ref ResourceCategory category, ref ResourceType type, ref int hash, ref Utf8GamePath path, Utf8GamePath original,
|
||||
private void ResourceHandler(ref ResourceCategory category, ref ResourceType type, ref int hash, ref Utf8GamePath path,
|
||||
Utf8GamePath original,
|
||||
GetResourceParameters* parameters, ref bool sync, ref ResourceHandle* returnValue)
|
||||
{
|
||||
if (returnValue != null)
|
||||
|
|
@ -75,7 +87,12 @@ public unsafe class ResourceLoader : IDisposable
|
|||
CompareHash(ComputeHash(path.Path, parameters), hash, path);
|
||||
|
||||
// If no replacements are being made, we still want to be able to trigger the event.
|
||||
var (resolvedPath, data) = _incMode.Value ? (null, ResolveData.Invalid) : ResolvePath(path, category, type);
|
||||
var (resolvedPath, data) = _incMode.Value
|
||||
? (null, ResolveData.Invalid)
|
||||
: _resolvedData.Valid
|
||||
? (_resolvedData.ModCollection.ResolvePath(path), _resolvedData)
|
||||
: ResolvePath(path, category, type);
|
||||
|
||||
if (resolvedPath == null || !Utf8GamePath.FromByteString(resolvedPath.Value.InternalName, out var p))
|
||||
{
|
||||
returnValue = _resources.GetOriginalResource(sync, category, type, hash, path.Path, parameters);
|
||||
|
|
@ -85,7 +102,7 @@ public unsafe class ResourceLoader : IDisposable
|
|||
|
||||
_texMdlService.AddCrc(type, resolvedPath);
|
||||
// Replace the hash and path with the correct one for the replacement.
|
||||
hash = ComputeHash(resolvedPath.Value.InternalName, parameters);
|
||||
hash = ComputeHash(resolvedPath.Value.InternalName, parameters);
|
||||
var oldPath = path;
|
||||
path = p;
|
||||
returnValue = _resources.GetOriginalResource(sync, category, type, hash, path.Path, parameters);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using Dalamud.Hooking;
|
||||
using Dalamud.Utility.Signatures;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.Structs;
|
||||
|
|
@ -60,7 +61,8 @@ public unsafe class ResourceService : IDisposable
|
|||
/// <param name="parameters">Mainly used for SCD streaming, can be null.</param>
|
||||
/// <param name="sync">Whether to request the resource synchronously or asynchronously.</param>
|
||||
/// <param name="returnValue">The returned resource handle. If this is not null, calling original will be skipped. </param>
|
||||
public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref ResourceType type, ref int hash, ref Utf8GamePath path, Utf8GamePath original,
|
||||
public delegate void GetResourcePreDelegate(ref ResourceCategory category, ref ResourceType type, ref int hash, ref Utf8GamePath path,
|
||||
Utf8GamePath original,
|
||||
GetResourceParameters* parameters, ref bool sync, ref ResourceHandle* returnValue);
|
||||
|
||||
/// <summary> <inheritdoc cref="GetResourcePreDelegate"/> <para/>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public sealed unsafe class DecalReverter : IDisposable
|
|||
private readonly Structs.TextureResourceHandle* _decal;
|
||||
private readonly Structs.TextureResourceHandle* _transparent;
|
||||
|
||||
public DecalReverter(Configuration config, CharacterUtility utility, ResourceService resources, ModCollection? collection, bool doDecal)
|
||||
public DecalReverter(Configuration config, CharacterUtility utility, ResourceLoader resources, ResolveData resolveData, bool doDecal)
|
||||
{
|
||||
_utility = utility;
|
||||
var ptr = _utility.Address;
|
||||
|
|
@ -30,16 +30,14 @@ public sealed unsafe class DecalReverter : IDisposable
|
|||
|
||||
if (doDecal)
|
||||
{
|
||||
var decalPath = collection?.ResolvePath(DecalPath)?.InternalName ?? DecalPath.Path;
|
||||
var decalHandle = resources.GetResource(ResourceCategory.Chara, ResourceType.Tex, decalPath);
|
||||
var decalHandle = resources.LoadResolvedResource(ResourceCategory.Chara, ResourceType.Tex, DecalPath.Path, resolveData);
|
||||
_decal = (Structs.TextureResourceHandle*)decalHandle;
|
||||
if (_decal != null)
|
||||
ptr->DecalTexResource = _decal;
|
||||
}
|
||||
else
|
||||
{
|
||||
var transparentPath = collection?.ResolvePath(TransparentPath)?.InternalName ?? TransparentPath.Path;
|
||||
var transparentHandle = resources.GetResource(ResourceCategory.Chara, ResourceType.Tex, transparentPath);
|
||||
var transparentHandle = resources.LoadResolvedResource(ResourceCategory.Chara, ResourceType.Tex, TransparentPath.Path, resolveData);
|
||||
_transparent = (Structs.TextureResourceHandle*)transparentHandle;
|
||||
if (_transparent != null)
|
||||
ptr->TransparentTexResource = _transparent;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue