public static int GfxFVFOffset(int fvfFlags, int a2)
{
int result = 0;
if (a2 != 0x2)
{
result += 12;
if (a2 != 0x10)
{
if ((fvfFlags & 0x10) != 0 /*D3DFVF_NORMAL*/ )
{
result = 24;
}
if ((fvfFlags & 0x20) != 0 /*D3DFVF_PSIZE*/ )
{
result += 4;
}
if (a2 != 0x40)
{
if ((fvfFlags & 0x40) != 0 /*D3DFVF_DIFFUSE*/ )
{
result += 4;
}
if ((fvfFlags & 0x80) != 0 /*D3DFVF_SPECULAR*/ )
{
result += 4;
}
if (a2 != 0x100)
{
result += 8;
}
}
}
}
return result / 4;
}
static int[] GfxBaseFVFSizes = { 0, 0, 12, 0, 16, 0, 16, 0, 20, 0, 24, 0, 28, 0, 32, 0 };
public static int GfxFVFSize(int fvfFlags)
{
int result = GfxBaseFVFSizes[fvfFlags & 0xF];
if ((fvfFlags & 0x10) != 0 /*D3DFVF_NORMAL*/ )
{
result += 12;
}
if ((fvfFlags & 0x20) != 0 /*D3DFVF_PSIZE*/ )
{
result += 4;
}
if ((fvfFlags & 0x40) != 0 /*D3DFVF_DIFFUSE*/ )
{
result += 4;
}
if ((fvfFlags & 0x80) != 0 /*D3DFVF_SPECULAR*/ )
{
result += 4;
}
if ((fvfFlags & 0x100) != 0) // 0x100
{
result += 8;
}
if ((fvfFlags & 0x200) != 0) // 0x200
{
result += 8;
}
return result / 4;
}
public class GfxPacket
{
public int Type;
public float[] Vertices;
public int[] Indices;
}
public class ModStatic
{
public int Fvf;
public List<GfxPacket> Packets;
public List<int> ShaderIndices;
}
public static ModStatic ReadModStatic(BinaryReader reader)
{
var result = new ModStatic();
var packetCount = reader.ReadInt32();
if ((packetCount & 0x80) != 0)
{
packetCount &= 0x7F;
result.Fvf = reader.ReadInt32();
result.ShaderIndices = reader.ReadBytes(packetCount).Select(x => (int) x).ToList();
}
else
{
var expectedVertices = reader.ReadInt32();
var expectedIndices = reader.ReadInt32();
var expectedPackets = reader.ReadInt32();
var fvf = reader.ReadInt32();
result.Fvf = fvf;
result.Packets = new List<GfxPacket>();
result.ShaderIndices = new List<int>();
var fvfOffset = GfxFVFOffset(fvf, 0x40);
var fvfSize = GfxFVFSize(fvf);
var totalVerts = 0;
var totalIndices = 0;
for (int i = 0; i < packetCount; ++i)
{
var stripCount = reader.ReadInt32();
result.ShaderIndices.Add(reader.ReadInt32());
for (int j = 0; j < stripCount; ++j)
{
var type = reader.ReadInt32();
var vertCount = reader.ReadInt32();
var verts = new float[fvfSize * vertCount];
for (int k = 0; k < vertCount; ++k)
{
for (int l = 0; l < fvfSize; ++l)
{
verts[(k * fvfSize) + l] = reader.ReadSingle();
}
if ((fvf & 0x40) != 0)
{
verts[(k * fvfSize) + fvfOffset] = SwapEndian(verts[(k * fvfSize) + fvfOffset]);
}
}
var indicesCount = reader.ReadInt32();
var indices = new int[indicesCount];
for (int k = 0; k < indices.Length; ++k)
{
indices[k] = reader.ReadUInt16();
}
result.Packets.Add(new GfxPacket
{
Type = type,
Vertices = verts,
Indices = indices
});
totalVerts += vertCount;
totalIndices += indicesCount;
}
}
Console.WriteLine("Verts: {0,3} (expected {1,3})", totalVerts, expectedVertices);
Console.WriteLine("Indices: {0,3} (expected {1,3})", totalIndices, expectedIndices);
Console.WriteLine("Packets: {0,3} (expected {1,3})", packetCount, expectedPackets);
}
return result;
}
Comments
0 B
|👍
/👎