mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 20:24:17 +01:00
Mtrl shader resource editing, ShPk editing
This commit is contained in:
parent
7ee80c7d48
commit
0c17892f03
12 changed files with 2535 additions and 63 deletions
123
Penumbra.GameData/Files/ShpkFile.Write.cs
Normal file
123
Penumbra.GameData/Files/ShpkFile.Write.cs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Penumbra.GameData.Files;
|
||||
|
||||
public partial class ShpkFile
|
||||
{
|
||||
public byte[] Write()
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
using var blobs = new MemoryStream();
|
||||
using (var w = new BinaryWriter(stream))
|
||||
{
|
||||
w.Write(ShPkMagic);
|
||||
w.Write(Unknown1);
|
||||
w.Write(DirectXVersion switch
|
||||
{
|
||||
DXVersion.DirectX9 => DX9Magic,
|
||||
DXVersion.DirectX11 => DX11Magic,
|
||||
_ => throw new NotImplementedException(),
|
||||
});
|
||||
long offsetsPosition = stream.Position;
|
||||
w.Write(0u); // Placeholder for file size
|
||||
w.Write(0u); // Placeholder for blobs offset
|
||||
w.Write(0u); // Placeholder for strings offset
|
||||
w.Write((uint)VertexShaders.Length);
|
||||
w.Write((uint)PixelShaders.Length);
|
||||
w.Write(MaterialParamsSize);
|
||||
w.Write((uint)MaterialParams.Length);
|
||||
w.Write((uint)Constants.Length);
|
||||
w.Write((uint)Samplers.Length);
|
||||
w.Write((uint)UnknownA.Length);
|
||||
w.Write((uint)UnknownB.Length);
|
||||
w.Write((uint)UnknownC.Length);
|
||||
w.Write(Unknown2);
|
||||
w.Write(Unknown3);
|
||||
w.Write(Unknown4);
|
||||
|
||||
WriteShaderArray(w, VertexShaders, blobs, Strings);
|
||||
WriteShaderArray(w, PixelShaders, blobs, Strings);
|
||||
|
||||
foreach (var materialParam in MaterialParams)
|
||||
{
|
||||
w.Write(materialParam.Id);
|
||||
w.Write(materialParam.ByteOffset);
|
||||
w.Write(materialParam.ByteSize);
|
||||
}
|
||||
|
||||
WriteResourceArray(w, Constants, Strings);
|
||||
WriteResourceArray(w, Samplers, Strings);
|
||||
|
||||
w.Write(Unknowns.Item1);
|
||||
w.Write(Unknowns.Item2);
|
||||
w.Write(Unknowns.Item3);
|
||||
|
||||
WriteUInt32PairArray(w, UnknownA);
|
||||
WriteUInt32PairArray(w, UnknownB);
|
||||
WriteUInt32PairArray(w, UnknownC);
|
||||
|
||||
w.Write(AdditionalData);
|
||||
|
||||
var blobsOffset = (int)stream.Position;
|
||||
blobs.WriteTo(stream);
|
||||
|
||||
var stringsOffset = (int)stream.Position;
|
||||
Strings.Data.WriteTo(stream);
|
||||
|
||||
var fileSize = (int)stream.Position;
|
||||
|
||||
stream.Seek(offsetsPosition, SeekOrigin.Begin);
|
||||
w.Write(fileSize);
|
||||
w.Write(blobsOffset);
|
||||
w.Write(stringsOffset);
|
||||
}
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
|
||||
private static void WriteResourceArray(BinaryWriter w, Resource[] array, StringPool strings)
|
||||
{
|
||||
foreach (var buf in array)
|
||||
{
|
||||
var (strOffset, strSize) = strings.FindOrAddString(buf.Name);
|
||||
w.Write(buf.Id);
|
||||
w.Write(strOffset);
|
||||
w.Write(strSize);
|
||||
w.Write(buf.Slot);
|
||||
w.Write(buf.Size);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteShaderArray(BinaryWriter w, Shader[] array, MemoryStream blobs, StringPool strings)
|
||||
{
|
||||
foreach (var shader in array)
|
||||
{
|
||||
var blobOffset = (int)blobs.Position;
|
||||
blobs.Write(shader.AdditionalHeader);
|
||||
blobs.Write(shader.Blob);
|
||||
var blobSize = (int)blobs.Position - blobOffset;
|
||||
|
||||
w.Write(blobOffset);
|
||||
w.Write(blobSize);
|
||||
w.Write((ushort)shader.Constants.Length);
|
||||
w.Write((ushort)shader.Samplers.Length);
|
||||
w.Write((ushort)shader.UnknownX.Length);
|
||||
w.Write((ushort)shader.UnknownY.Length);
|
||||
|
||||
WriteResourceArray(w, shader.Constants, strings);
|
||||
WriteResourceArray(w, shader.Samplers, strings);
|
||||
WriteResourceArray(w, shader.UnknownX, strings);
|
||||
WriteResourceArray(w, shader.UnknownY, strings);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteUInt32PairArray(BinaryWriter w, (uint, uint)[] array)
|
||||
{
|
||||
foreach (var (first, second) in array)
|
||||
{
|
||||
w.Write(first);
|
||||
w.Write(second);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue