mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +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;
|
return samplers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MtrlFile(byte[] data, Func<string, ShpkFile?>? loadAssociatedShpk = null)
|
public MtrlFile(byte[] data)
|
||||||
{
|
{
|
||||||
using var stream = new MemoryStream(data);
|
using var stream = new MemoryStream(data);
|
||||||
using var r = new BinaryReader(stream);
|
using var r = new BinaryReader(stream);
|
||||||
|
|
@ -133,8 +133,6 @@ public partial class MtrlFile : IWritable
|
||||||
|
|
||||||
ShaderPackage.Name = UseOffset(strings, shaderPackageNameOffset);
|
ShaderPackage.Name = UseOffset(strings, shaderPackageNameOffset);
|
||||||
|
|
||||||
AssociatedShpk = loadAssociatedShpk?.Invoke(ShaderPackage.Name);
|
|
||||||
|
|
||||||
AdditionalData = r.ReadBytes(additionalDataSize);
|
AdditionalData = r.ReadBytes(additionalDataSize);
|
||||||
for (var i = 0; i < ColorSets.Length; ++i)
|
for (var i = 0; i < ColorSets.Length; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
@ -17,7 +16,6 @@ using Penumbra.GameData.Files;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
using Penumbra.String.Functions;
|
using Penumbra.String.Functions;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
using static Penumbra.GameData.Files.ShpkFile;
|
|
||||||
|
|
||||||
namespace Penumbra.UI.Classes;
|
namespace Penumbra.UI.Classes;
|
||||||
|
|
||||||
|
|
@ -31,6 +29,35 @@ public partial class ModEditWindow
|
||||||
private uint _materialNewConstantId = 0;
|
private uint _materialNewConstantId = 0;
|
||||||
private uint _materialNewSamplerId = 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 )
|
private bool DrawMaterialPanel( MtrlFile file, bool disabled )
|
||||||
{
|
{
|
||||||
var ret = DrawMaterialTextureChange( file, 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 );
|
ImGui.InputTextWithHint( "##swapValue", "... instead of this file.", ref _newSwapKey, Utf8GamePath.MaxGamePathLength );
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME this probably doesn't belong here
|
/// <summary>
|
||||||
private T? LoadAssociatedFile<T>( string gamePath, Func< byte[], T? > parse )
|
/// 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;
|
var currentFile = Penumbra.CollectionManager.Current.ResolvePath( path );
|
||||||
if( defaultFiles != null )
|
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 value;
|
||||||
{
|
|
||||||
return parse( File.ReadAllBytes( fsPath.FullName ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
utf8Path.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var file = Dalamud.GameData.GetFile( gamePath )?.Data;
|
return new FullPath( path );
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModEditWindow()
|
public ModEditWindow()
|
||||||
|
|
@ -583,7 +574,7 @@ public partial class ModEditWindow : Window, IDisposable
|
||||||
() => _editor?.MtrlFiles ?? Array.Empty< Editor.FileRegistry >(),
|
() => _editor?.MtrlFiles ?? Array.Empty< Editor.FileRegistry >(),
|
||||||
DrawMaterialPanel,
|
DrawMaterialPanel,
|
||||||
() => _mod?.ModPath.FullName ?? string.Empty,
|
() => _mod?.ModPath.FullName ?? string.Empty,
|
||||||
bytes => new MtrlFile( bytes, LoadAssociatedShpk ) );
|
LoadMtrl );
|
||||||
_modelTab = new FileEditor< MdlFile >( "Models", ".mdl",
|
_modelTab = new FileEditor< MdlFile >( "Models", ".mdl",
|
||||||
() => _editor?.MdlFiles ?? Array.Empty< Editor.FileRegistry >(),
|
() => _editor?.MdlFiles ?? Array.Empty< Editor.FileRegistry >(),
|
||||||
DrawModelPanel,
|
DrawModelPanel,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue