mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Change handling of associated shpk for material.
This commit is contained in:
parent
a2b62a8b6a
commit
7e56858bc6
3 changed files with 53 additions and 37 deletions
|
|
@ -94,7 +94,7 @@ public partial class MtrlFile : IWritable
|
|||
return samplers;
|
||||
}
|
||||
|
||||
public MtrlFile(byte[] data, Func<string, ShpkFile?>? loadAssociatedShpk = null)
|
||||
public MtrlFile(byte[] data)
|
||||
{
|
||||
using var stream = new MemoryStream(data);
|
||||
using var r = new BinaryReader(stream);
|
||||
|
|
@ -133,8 +133,6 @@ public partial class MtrlFile : IWritable
|
|||
|
||||
ShaderPackage.Name = UseOffset(strings, shaderPackageNameOffset);
|
||||
|
||||
AssociatedShpk = loadAssociatedShpk?.Invoke(ShaderPackage.Name);
|
||||
|
||||
AdditionalData = r.ReadBytes(additionalDataSize);
|
||||
for (var i = 0; i < ColorSets.Length; ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
|
|
@ -17,7 +16,6 @@ using Penumbra.GameData.Files;
|
|||
using Penumbra.String.Classes;
|
||||
using Penumbra.String.Functions;
|
||||
using Penumbra.Util;
|
||||
using static Penumbra.GameData.Files.ShpkFile;
|
||||
|
||||
namespace Penumbra.UI.Classes;
|
||||
|
||||
|
|
@ -31,6 +29,35 @@ public partial class ModEditWindow
|
|||
private uint _materialNewConstantId = 0;
|
||||
private uint _materialNewSamplerId = 0;
|
||||
|
||||
/// <summary> Load the material with an associated shader package if it can be found. See <seealso cref="FindBestMatch"/>. </summary>
|
||||
private MtrlFile LoadMtrl( byte[] bytes )
|
||||
{
|
||||
var mtrl = new MtrlFile( bytes );
|
||||
if( !Utf8GamePath.FromString( $"shader/sm5/shpk/{mtrl.ShaderPackage.Name}", out var shpkPath, true ) )
|
||||
{
|
||||
return mtrl;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var shpkFilePath = FindBestMatch( shpkPath );
|
||||
var data = shpkFilePath.IsRooted
|
||||
? File.ReadAllBytes( shpkFilePath.FullName )
|
||||
: Dalamud.GameData.GetFile( shpkFilePath.FullName )?.Data;
|
||||
if( data?.Length > 0 )
|
||||
{
|
||||
mtrl.AssociatedShpk = new ShpkFile( data );
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Debug( $"Could not parse associated file {shpkPath} to Shpk:\n{e}" );
|
||||
mtrl.AssociatedShpk = null;
|
||||
}
|
||||
|
||||
return mtrl;
|
||||
}
|
||||
|
||||
private bool DrawMaterialPanel( MtrlFile file, bool disabled )
|
||||
{
|
||||
var ret = DrawMaterialTextureChange( file, disabled );
|
||||
|
|
|
|||
|
|
@ -535,45 +535,36 @@ public partial class ModEditWindow : Window, IDisposable
|
|||
ImGui.InputTextWithHint( "##swapValue", "... instead of this file.", ref _newSwapKey, Utf8GamePath.MaxGamePathLength );
|
||||
}
|
||||
|
||||
// FIXME this probably doesn't belong here
|
||||
private T? LoadAssociatedFile<T>( string gamePath, Func< byte[], T? > parse )
|
||||
/// <summary>
|
||||
/// Find the best matching associated file for a given path.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Tries to resolve from the current collection first and chooses the currently resolved file if any exists.
|
||||
/// If none exists, goes through all options in the currently selected mod (if any) in order of priority and resolves in them.
|
||||
/// If no redirection is found in either of those options, returns the original path.
|
||||
/// </remarks>
|
||||
private FullPath FindBestMatch( Utf8GamePath path )
|
||||
{
|
||||
var defaultFiles = _mod?.Default?.Files;
|
||||
if( defaultFiles != null )
|
||||
var currentFile = Penumbra.CollectionManager.Current.ResolvePath( path );
|
||||
if( currentFile != null )
|
||||
{
|
||||
if( Utf8GamePath.FromString( gamePath, out var utf8Path, true ) )
|
||||
return currentFile.Value;
|
||||
}
|
||||
|
||||
if( _mod != null )
|
||||
{
|
||||
foreach( var option in _mod.Groups.OrderByDescending( g => g.Priority )
|
||||
.SelectMany( g => g.WithIndex().OrderByDescending( o => g.OptionPriority( o.Index ) ).Select( g => g.Value ) )
|
||||
.Append( _mod.Default ) )
|
||||
{
|
||||
try
|
||||
if( option.Files.TryGetValue( path, out var value ) || option.FileSwaps.TryGetValue( path, out value ) )
|
||||
{
|
||||
if (defaultFiles.TryGetValue( utf8Path, out var fsPath ))
|
||||
{
|
||||
return parse( File.ReadAllBytes( fsPath.FullName ) );
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
utf8Path.Dispose();
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var file = Dalamud.GameData.GetFile( gamePath )?.Data;
|
||||
return file == null ? default : parse( file );
|
||||
}
|
||||
|
||||
// FIXME neither does this
|
||||
private ShpkFile? LoadAssociatedShpk( string shaderName )
|
||||
{
|
||||
var path = $"shader/sm5/shpk/{shaderName}";
|
||||
try
|
||||
{
|
||||
return LoadAssociatedFile( path, file => new ShpkFile( file ) );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Debug( $"Could not parse associated file {path} to Shpk:\n{e}" );
|
||||
return null;
|
||||
}
|
||||
return new FullPath( path );
|
||||
}
|
||||
|
||||
public ModEditWindow()
|
||||
|
|
@ -583,7 +574,7 @@ public partial class ModEditWindow : Window, IDisposable
|
|||
() => _editor?.MtrlFiles ?? Array.Empty< Editor.FileRegistry >(),
|
||||
DrawMaterialPanel,
|
||||
() => _mod?.ModPath.FullName ?? string.Empty,
|
||||
bytes => new MtrlFile( bytes, LoadAssociatedShpk ) );
|
||||
LoadMtrl );
|
||||
_modelTab = new FileEditor< MdlFile >( "Models", ".mdl",
|
||||
() => _editor?.MdlFiles ?? Array.Empty< Editor.FileRegistry >(),
|
||||
DrawModelPanel,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue