public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.WriteSignature("VTX1".ToCharArray()); writer.Write(0); // Placeholder for section size writer.Write(0x40); // Offset to attribute data for (int i = 0; i < 13; i++) // Placeholders for attribute data offsets { writer.Write(0); } WriteAttributeHeaders(writer); StreamUtility.PadStreamWithString(writer, 32); WriteAttributeData(writer, (int)start); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }
public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.Write("DRW1".ToCharArray()); writer.Write(0); // Placeholder for section size writer.Write((short)WeightTypeCheck.Count); writer.Write((short)-1); writer.Write(20); // Offset to weight type bools, always 20 writer.Write(20 + WeightTypeCheck.Count); // Offset to indices, always 20 + number of weight type bools foreach (bool bol in WeightTypeCheck) { writer.Write(bol); } foreach (int inte in Indices) { writer.Write((short)inte); } StreamUtility.PadStreamWithString(writer, 32); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }
public static void Write(EndianBinaryWriter writer, List <ChannelControl> channels) { foreach (ChannelControl chan in channels) { chan.Write(writer); } StreamUtility.PadStreamWithString(writer, 4); }
public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.Write("JNT1".ToCharArray()); writer.Write(0); // Placeholder for section size writer.Write((short)FlatSkeleton.Count); writer.Write((short)-1); writer.Write(24); // Offset to joint data, always 24 writer.Write(0); // Placeholder for remap data offset writer.Write(0); // Placeholder for name table offset List <string> names = new List <string>(); foreach (Rigging.Bone bone in FlatSkeleton) { writer.Write(bone.ToBytes()); names.Add(bone.Name); } long curOffset = writer.BaseStream.Position; writer.Seek((int)(start + 16), System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); for (int i = 0; i < FlatSkeleton.Count; i++) { writer.Write((short)i); } StreamUtility.PadStreamWithString(writer, 8); curOffset = writer.BaseStream.Position; writer.Seek((int)(start + 20), System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); NameTableIO.Write(writer, names); StreamUtility.PadStreamWithString(writer, 32); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }
public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.Write("EVP1".ToCharArray()); writer.Write(0); // Placeholder for section size writer.Write((short)Weights.Count); writer.Write((short)-1); if (Weights.Count == 0) { writer.Write((int)0); writer.Write((int)0); writer.Write((int)0); writer.Write((int)0); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write(32); writer.Seek(0, System.IO.SeekOrigin.End); StreamUtility.PadStreamWithString(writer, 8); return; } writer.Write(28); // Offset to weight count data. Always 28 writer.Write(28 + Weights.Count); // Offset to bone/weight indices. Always 28 + the number of weights writer.Write(0); // Placeholder for weight data offset writer.Write(0); // Placeholder for inverse bind matrix data offset foreach (Weight w in Weights) { writer.Write((byte)w.WeightCount); } foreach (Weight w in Weights) { foreach (int inte in w.BoneIndices) { writer.Write((short)inte); } } StreamUtility.PadStreamWithString(writer, 8); long curOffset = writer.BaseStream.Position; writer.Seek((int)start + 20, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (Weight w in Weights) { foreach (float fl in w.Weights) { writer.Write(fl); } } curOffset = writer.BaseStream.Position; writer.Seek((int)start + 24, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (Matrix4 mat in InverseBindMatrices) { Vector4 Row1 = mat.Column0; Vector4 Row2 = mat.Column1; Vector4 Row3 = mat.Column2; writer.Write(Row1.X); writer.Write(Row1.Y); writer.Write(Row1.Z); writer.Write(Row1.W); writer.Write(Row2.X); writer.Write(Row2.Y); writer.Write(Row2.Z); writer.Write(Row2.W); writer.Write(Row3.X); writer.Write(Row3.Y); writer.Write(Row3.Z); writer.Write(Row3.W); } StreamUtility.PadStreamWithString(writer, 32); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }
public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.Write("TEX1".ToCharArray()); writer.Write(0); // Placeholder for section size writer.Write((short)Textures.Count); writer.Write((short)-1); writer.Write(32); // Offset to the start of the texture data. Always 32 writer.Write(0); // Placeholder for string table offset StreamUtility.PadStreamWithString(writer, 32); List <string> names = new List <string>(); Dictionary <string, Tuple <byte[], ushort[]> > image_palette_Data = new Dictionary <string, Tuple <byte[], ushort[]> >(); Dictionary <string, int> imageDataOffsets = new Dictionary <string, int>(); Dictionary <string, int> paletteDataOffsets = new Dictionary <string, int>(); foreach (BinaryTextureImage img in Textures) { names.Add(img.Name); img.WriteHeader(writer); if (!image_palette_Data.ContainsKey(img.Name)) { image_palette_Data.Add(img.Name, img.EncodeData()); imageDataOffsets.Add(img.Name, 0); paletteDataOffsets.Add(img.Name, 0); } } long curOffset = writer.BaseStream.Position; // Write the palette data and note the offset in paletteDataOffsets foreach (string key in image_palette_Data.Keys) { paletteDataOffsets[key] = (int)(curOffset - start); if (image_palette_Data[key].Item2.Length > 0) { foreach (ushort st in image_palette_Data[key].Item2) { writer.Write(st); } StreamUtility.PadStreamWithString(writer, 32); } curOffset = writer.BaseStream.Position; } // Write the image data and note the offset in imageDataOffsets foreach (string key in image_palette_Data.Keys) { imageDataOffsets[key] = (int)(curOffset - start); writer.Write(image_palette_Data[key].Item1); curOffset = writer.BaseStream.Position; } // Write texture name table offset writer.Seek((int)start + 16, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); NameTableIO.Write(writer, names); StreamUtility.PadStreamWithString(writer, 32); long end = writer.BaseStream.Position; long length = (end - start); // Write TEX1 size writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); writer.Seek((int)start + 32, SeekOrigin.Begin); // Write palette and image data offsets to headers for (int i = 0; i < Textures.Count; i++) { int header_offset_const = 32 + i * 32; // Start is the beginning of the TEX1 section; // (i * 32) is the offset of the header in the header data block; // 32 is the offset of the header data block from the beginning of TEX1; // 12 is the offset of the palette data offset in the header writer.Seek((int)start + (i * 32) + 32 + 12, SeekOrigin.Begin); writer.Write(paletteDataOffsets[Textures[i].Name] - header_offset_const); // Same as above, except instead of 12 it's 28. // 28 is the offset of the image data offset in the header writer.Seek((int)start + (i * 32) + 32 + 28, SeekOrigin.Begin); writer.Write(imageDataOffsets[Textures[i].Name] - header_offset_const); } }
public void Write(EndianBinaryWriter writer) { List <Tuple <ShapeVertexDescriptor, int> > descriptorOffsets; // Contains the offsets for each unique vertex descriptor List <Tuple <Packet, int> > packetMatrixOffsets; // Contains the offsets for each packet's matrix indices List <Tuple <int, int> > packetPrimitiveOffsets; // Contains the offsets for each packet's first primitive long start = writer.BaseStream.Position; writer.Write("SHP1".ToCharArray()); writer.Write(0); // Placeholder for section offset writer.Write((short)Shapes.Count); writer.Write((short)-1); writer.Write(44); // Offset to shape header data. Always 48 for (int i = 0; i < 7; i++) { writer.Write(0); } foreach (Shape shp in Shapes) { shp.Write(writer); } // Remap table offset writer.Seek((int)(start + 16), System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - start)); writer.Seek((int)(writer.BaseStream.Length), System.IO.SeekOrigin.Begin); for (int i = 0; i < Shapes.Count; i++) { writer.Write((short)i); } StreamUtility.PadStreamWithString(writer, 32); // Attribute descriptor data offset writer.Seek((int)(start + 24), System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - start)); writer.Seek((int)(writer.BaseStream.Length), System.IO.SeekOrigin.Begin); descriptorOffsets = WriteShapeAttributeDescriptors(writer); // Packet matrix index data offset writer.Seek((int)(start + 28), System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - start)); writer.Seek((int)(writer.BaseStream.Length), System.IO.SeekOrigin.Begin); packetMatrixOffsets = WritePacketMatrixIndices(writer); StreamUtility.PadStreamWithString(writer, 32); // Primitive data offset writer.Seek((int)(start + 32), System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - start)); writer.Seek((int)(writer.BaseStream.Length), System.IO.SeekOrigin.Begin); packetPrimitiveOffsets = WritePrimitives(writer); // Packet matrix index metadata offset writer.Seek((int)(start + 36), System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - start)); writer.Seek((int)(writer.BaseStream.Length), System.IO.SeekOrigin.Begin); foreach (Tuple <Packet, int> tup in packetMatrixOffsets) { writer.Write((short)0); // ??? writer.Write((short)tup.Item1.MatrixIndices.Count); writer.Write(tup.Item2); } // Packet primitive metadata offset writer.Seek((int)(start + 40), System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - start)); writer.Seek((int)(writer.BaseStream.Length), System.IO.SeekOrigin.Begin); foreach (Tuple <int, int> tup in packetPrimitiveOffsets) { writer.Write(tup.Item1); writer.Write(tup.Item2); } StreamUtility.PadStreamWithString(writer, 32); writer.Seek((int)(start + 44), System.IO.SeekOrigin.Begin); foreach (Shape shape in Shapes) { writer.Seek(4, System.IO.SeekOrigin.Current); writer.Write((short)descriptorOffsets.Find(x => x.Item1 == shape.Descriptor).Item2); writer.Write((short)packetMatrixOffsets.IndexOf(packetMatrixOffsets.Find(x => x.Item1 == shape.Packets[0]))); writer.Write((short)packetMatrixOffsets.IndexOf(packetMatrixOffsets.Find(x => x.Item1 == shape.Packets[0]))); writer.Seek(30, System.IO.SeekOrigin.Current); } writer.Seek((int)writer.BaseStream.Length, System.IO.SeekOrigin.Begin); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }
private void WriteAttributeData(EndianBinaryWriter writer, int baseOffset) { foreach (GXVertexAttribute attrib in Enum.GetValues(typeof(GXVertexAttribute))) { if (!Attributes.CheckAttribute(attrib) || attrib == GXVertexAttribute.PositionMatrixIdx) { continue; } long endOffset = writer.BaseStream.Position; switch (attrib) { case GXVertexAttribute.Position: writer.Seek(baseOffset + 0x0C, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Vector3 posVec in (List <Vector3>)Attributes.GetAttributeData(attrib)) { switch (StorageFormats[attrib].Item1) { case GXDataType.Unsigned8: writer.Write((byte)Math.Round(posVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((byte)Math.Round(posVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((byte)Math.Round(posVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Signed8: writer.Write((sbyte)Math.Round(posVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((sbyte)Math.Round(posVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((sbyte)Math.Round(posVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Unsigned16: writer.Write((ushort)Math.Round(posVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((ushort)Math.Round(posVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((ushort)Math.Round(posVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Signed16: writer.Write((short)Math.Round(posVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((short)Math.Round(posVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((short)Math.Round(posVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Float32: writer.Write(posVec); break; } } break; case GXVertexAttribute.Normal: writer.Seek(baseOffset + 0x10, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Vector3 normVec in Attributes.Normals) { switch (StorageFormats[attrib].Item1) { case GXDataType.Unsigned8: writer.Write((byte)Math.Round(normVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((byte)Math.Round(normVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((byte)Math.Round(normVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Signed8: writer.Write((sbyte)Math.Round(normVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((sbyte)Math.Round(normVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((sbyte)Math.Round(normVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Unsigned16: writer.Write((ushort)Math.Round(normVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((ushort)Math.Round(normVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((ushort)Math.Round(normVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Signed16: writer.Write((short)Math.Round(normVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((short)Math.Round(normVec.Y * (1 << StorageFormats[attrib].Item2))); writer.Write((short)Math.Round(normVec.Z * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Float32: writer.Write(normVec); break; } } break; case GXVertexAttribute.Color0: case GXVertexAttribute.Color1: writer.Seek(baseOffset + 0x18 + (int)(attrib - 11) * 4, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Color col in (List <Color>)Attributes.GetAttributeData(attrib)) { writer.Write(col); } break; case GXVertexAttribute.Tex0: case GXVertexAttribute.Tex1: case GXVertexAttribute.Tex2: case GXVertexAttribute.Tex3: case GXVertexAttribute.Tex4: case GXVertexAttribute.Tex5: case GXVertexAttribute.Tex6: case GXVertexAttribute.Tex7: writer.Seek(baseOffset + 0x20 + (int)(attrib - 13) * 4, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Vector2 texVec in (List <Vector2>)Attributes.GetAttributeData(attrib)) { switch (StorageFormats[attrib].Item1) { case GXDataType.Unsigned8: writer.Write((byte)Math.Round(texVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((byte)Math.Round(texVec.Y * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Signed8: writer.Write((sbyte)Math.Round(texVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((sbyte)Math.Round(texVec.Y * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Unsigned16: writer.Write((ushort)Math.Round(texVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((ushort)Math.Round(texVec.Y * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Signed16: writer.Write((short)Math.Round(texVec.X * (1 << StorageFormats[attrib].Item2))); writer.Write((short)Math.Round(texVec.Y * (1 << StorageFormats[attrib].Item2))); break; case GXDataType.Float32: writer.Write(texVec); break; } } break; } StreamUtility.PadStreamWithString(writer, 32); } }
public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.Write("MAT3".ToCharArray()); writer.Write(0); // Placeholder for section offset writer.Write((short)m_RemapIndices.Count); writer.Write((short)-1); writer.Write(132); // Offset to material init data. Always 132 for (int i = 0; i < 29; i++) { writer.Write(0); } bool[] writtenCheck = new bool[m_Materials.Count]; List <string> names = m_MaterialNames; for (int i = 0; i < m_RemapIndices.Count; i++) { if (writtenCheck[m_RemapIndices[i]]) { continue; } else { WriteMaterialInitData(writer, m_Materials[m_RemapIndices[i]]); writtenCheck[m_RemapIndices[i]] = true; } } long curOffset = writer.BaseStream.Position; // Remap indices offset writer.Seek((int)start + 16, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); for (int i = 0; i < m_RemapIndices.Count; i++) { writer.Write((short)m_RemapIndices[i]); } curOffset = writer.BaseStream.Position; // Name table offset writer.Seek((int)start + 20, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); NameTableIO.Write(writer, names); StreamUtility.PadStreamWithString(writer, 8); curOffset = writer.BaseStream.Position; // Indirect texturing offset writer.Seek((int)start + 24, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); IndirectTexturingIO.Write(writer, m_IndirectTexBlock); curOffset = writer.BaseStream.Position; // Cull mode offset writer.Seek((int)start + 28, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); CullModeIO.Write(writer, m_CullModeBlock); curOffset = writer.BaseStream.Position; // Material colors offset writer.Seek((int)start + 32, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); ColorIO.Write(writer, m_MaterialColorBlock); curOffset = writer.BaseStream.Position; // Color channel count offset writer.Seek((int)start + 36, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (byte chanNum in NumColorChannelsBlock) { writer.Write(chanNum); } StreamUtility.PadStreamWithStringByOffset(writer, (int)(writer.BaseStream.Position - curOffset), 4); curOffset = writer.BaseStream.Position; // Color channel data offset writer.Seek((int)start + 40, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); ColorChannelIO.Write(writer, m_ChannelControlBlock); curOffset = writer.BaseStream.Position; // ambient color data offset writer.Seek((int)start + 44, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); ColorIO.Write(writer, m_AmbientColorBlock); curOffset = writer.BaseStream.Position; // light color data offset writer.Seek((int)start + 48, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); if (m_LightingColorBlock != null) { ColorIO.Write(writer, m_LightingColorBlock); } curOffset = writer.BaseStream.Position; // tex gen count data offset writer.Seek((int)start + 52, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (byte texGenCnt in NumTexGensBlock) { writer.Write(texGenCnt); } StreamUtility.PadStreamWithStringByOffset(writer, (int)(writer.BaseStream.Position - curOffset), 4); curOffset = writer.BaseStream.Position; // tex coord 1 data offset writer.Seek((int)start + 56, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TexCoordGenIO.Write(writer, m_TexCoord1GenBlock); curOffset = writer.BaseStream.Position; if (m_TexCoord2GenBlock != null) { // tex coord 2 data offset writer.Seek((int)start + 60, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TexCoordGenIO.Write(writer, m_TexCoord2GenBlock); } else { writer.Seek((int)start + 60, System.IO.SeekOrigin.Begin); writer.Write((int)0); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); } curOffset = writer.BaseStream.Position; // tex matrix 1 data offset writer.Seek((int)start + 64, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TexMatrixIO.Write(writer, m_TexMatrix1Block); curOffset = writer.BaseStream.Position; if (m_TexMatrix2Block != null) { // tex matrix 1 data offset writer.Seek((int)start + 68, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TexMatrixIO.Write(writer, m_TexMatrix2Block); } else { writer.Seek((int)start + 60, System.IO.SeekOrigin.Begin); writer.Write((int)0); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); } curOffset = writer.BaseStream.Position; // tex number data offset writer.Seek((int)start + 72, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (int inte in m_TexRemapBlock) { writer.Write((short)inte); } StreamUtility.PadStreamWithString(writer, 4); curOffset = writer.BaseStream.Position; // tev order data offset writer.Seek((int)start + 76, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TevOrderIO.Write(writer, m_TevOrderBlock); curOffset = writer.BaseStream.Position; // tev color data offset writer.Seek((int)start + 80, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); Int16ColorIO.Write(writer, m_TevColorBlock); curOffset = writer.BaseStream.Position; // tev konst color data offset writer.Seek((int)start + 84, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); ColorIO.Write(writer, m_TevKonstColorBlock); curOffset = writer.BaseStream.Position; // tev stage count data offset writer.Seek((int)start + 88, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (byte bt in NumTevStagesBlock) { writer.Write(bt); } StreamUtility.PadStreamWithStringByOffset(writer, (int)(writer.BaseStream.Position - curOffset), 4); curOffset = writer.BaseStream.Position; // tev stage data offset writer.Seek((int)start + 92, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TevStageIO.Write(writer, m_TevStageBlock); curOffset = writer.BaseStream.Position; // tev swap mode offset writer.Seek((int)start + 96, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TevSwapModeIO.Write(writer, m_SwapModeBlock); curOffset = writer.BaseStream.Position; // tev swap mode table offset writer.Seek((int)start + 100, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); TevSwapModeTableIO.Write(writer, m_SwapTableBlock); curOffset = writer.BaseStream.Position; // fog data offset writer.Seek((int)start + 104, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); FogIO.Write(writer, m_FogBlock); curOffset = writer.BaseStream.Position; // alpha compare offset writer.Seek((int)start + 108, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); AlphaCompareIO.Write(writer, m_AlphaCompBlock); curOffset = writer.BaseStream.Position; // blend data offset writer.Seek((int)start + 112, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); BlendModeIO.Write(writer, m_blendModeBlock); curOffset = writer.BaseStream.Position; // zmode data offset writer.Seek((int)start + 116, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); ZModeIO.Write(writer, m_zModeBlock); curOffset = writer.BaseStream.Position; // z comp loc data offset writer.Seek((int)start + 120, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (bool bol in m_zCompLocBlock) { writer.Write(bol); } StreamUtility.PadStreamWithStringByOffset(writer, (int)(writer.BaseStream.Position - curOffset), 4); curOffset = writer.BaseStream.Position; if (m_ditherBlock != null) { // dither data offset writer.Seek((int)start + 124, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); foreach (bool bol in m_ditherBlock) { writer.Write(bol); } StreamUtility.PadStreamWithStringByOffset(writer, (int)(writer.BaseStream.Position - curOffset), 4); } curOffset = writer.BaseStream.Position; // NBT Scale data offset writer.Seek((int)start + 128, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); NBTScaleIO.Write(writer, m_NBTScaleBlock); StreamUtility.PadStreamWithString(writer, 32); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }
public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.WriteSignature("MDL3".ToCharArray()); writer.Write(0); // Placeholder for section size writer.Write((short)Entries.Count); writer.Write((short)-1); writer.Write(0x40); // Offset to command data offset/size block writer.Write(0); writer.Write(0); writer.Write(0); writer.Write(0); writer.Write(0); StreamUtility.PadStreamWithString(writer, 32); long cmdBlockStart = writer.BaseStream.Position; for (int i = 0; i < Entries.Count; i++) { writer.Write(0); writer.Write(0); } StreamUtility.PadStreamWithString(writer, 32); for (int i = 0; i < Entries.Count; i++) { long absoluteStartOffset = writer.BaseStream.Position; long relativeStartOffset = writer.BaseStream.Position - cmdBlockStart - i * 8; Entries[i].Write(writer); StreamUtility.PadStreamWithZero(writer, 32); long size = writer.BaseStream.Position - absoluteStartOffset; writer.Seek((int)cmdBlockStart + (i * 8), System.IO.SeekOrigin.Begin); writer.Write((int)relativeStartOffset); writer.Write((int)size); writer.Seek(0, System.IO.SeekOrigin.End); } long subsection2StartOffset = writer.BaseStream.Position; writer.Seek((int)start + 0x10, System.IO.SeekOrigin.Begin); var x = (int)subsection2StartOffset - start; writer.Write((int)(subsection2StartOffset - start)); writer.Seek((int)subsection2StartOffset, System.IO.SeekOrigin.Begin); for (int i = 0; i < Entries.Count; i++) { writer.Write(0); writer.Write(0); writer.Write(0); writer.Write(0); } long subsection3StartOffset = writer.BaseStream.Position; writer.Seek((int)start + 0x14, System.IO.SeekOrigin.Begin); writer.Write((int)(subsection3StartOffset - start)); writer.Seek((int)subsection3StartOffset, System.IO.SeekOrigin.Begin); for (int i = 0; i < Entries.Count; i++) { writer.Write(0); writer.Write(0); } long subsection4StartOffset = writer.BaseStream.Position; writer.Seek((int)start + 0x18, System.IO.SeekOrigin.Begin); writer.Write((int)(subsection4StartOffset - start)); writer.Seek((int)subsection4StartOffset, System.IO.SeekOrigin.Begin); for (int i = 0; i < Entries.Count; i++) { writer.Write((byte)1); } StreamUtility.PadStreamWithString(writer, 4); long subsection5StartOffset = writer.BaseStream.Position; writer.Seek((int)start + 0x1C, System.IO.SeekOrigin.Begin); writer.Write((int)(subsection5StartOffset - start)); writer.Seek((int)subsection5StartOffset, System.IO.SeekOrigin.Begin); for (int i = 0; i < Entries.Count; i++) { writer.Write((short)i); } StreamUtility.PadStreamWithString(writer, 4); long stringTableStartOffset = writer.BaseStream.Position; writer.Seek((int)start + 0x20, System.IO.SeekOrigin.Begin); writer.Write((int)(stringTableStartOffset - start)); writer.Seek((int)stringTableStartOffset, System.IO.SeekOrigin.Begin); writer.Write((short)0); StreamUtility.PadStreamWithString(writer, 32); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }
private void WriteAttributeData(EndianBinaryWriter writer, int baseOffset) { foreach (GXVertexAttribute attrib in Enum.GetValues(typeof(GXVertexAttribute))) { if (!Attributes.CheckAttribute(attrib) || attrib == GXVertexAttribute.PositionMatrixIdx) { continue; } long endOffset = writer.BaseStream.Position; switch (attrib) { case GXVertexAttribute.Position: writer.Seek(baseOffset + 0x0C, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Vector3 vec3 in Attributes.Positions) { writer.Write(vec3); } break; case GXVertexAttribute.Normal: writer.Seek(baseOffset + 0x10, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Vector3 vec3 in Attributes.Normals) { writer.Write(vec3); } break; case GXVertexAttribute.Color0: case GXVertexAttribute.Color1: writer.Seek(baseOffset + 0x18 + (int)(attrib - 11) * 4, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Color col in (List <Color>)Attributes.GetAttributeData(attrib)) { writer.Write(col); } break; case GXVertexAttribute.Tex0: case GXVertexAttribute.Tex1: case GXVertexAttribute.Tex2: case GXVertexAttribute.Tex3: case GXVertexAttribute.Tex4: case GXVertexAttribute.Tex5: case GXVertexAttribute.Tex6: case GXVertexAttribute.Tex7: writer.Seek(baseOffset + 0x20 + (int)(attrib - 13) * 4, System.IO.SeekOrigin.Begin); writer.Write((int)(writer.BaseStream.Length - baseOffset)); writer.Seek((int)endOffset, System.IO.SeekOrigin.Begin); foreach (Vector2 vec2 in (List <Vector2>)Attributes.GetAttributeData(attrib)) { writer.Write(vec2); } break; } StreamUtility.PadStreamWithString(writer, 32); } }
public void Write(EndianBinaryWriter writer) { long start = writer.BaseStream.Position; writer.Write("TEX1".ToCharArray()); writer.Write(0); // Placeholder for section size writer.Write((short)Textures.Count); writer.Write((short)-1); writer.Write(32); // Offset to the start of the texture data. Always 32 writer.Write(0); // Placeholder for string table offset StreamUtility.PadStreamWithString(writer, 32); List <string> names = new List <string>(); List <Tuple <byte[], ushort[]> > imgData = new List <Tuple <byte[], ushort[]> >(); foreach (BinaryTextureImage img in Textures) { imgData.Add(img.EncodeData()); img.WriteHeader(writer); names.Add(img.Name); } long curOffset = writer.BaseStream.Position; // Palette pass for (int i = 0; i < imgData.Count; i++) { writer.Seek((int)start + (i * 32) + 44, System.IO.SeekOrigin.Begin); // offset of the image header + 32 bytes for the section's header + 12 bytes into the image header for palette offset writer.Write((int)(curOffset - start) - (32 + i * 32)); // Offsets are relative to the start of the image header writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); if (imgData[i].Item2.Length > 0) { foreach (ushort st in imgData[i].Item2) { writer.Write(st); } StreamUtility.PadStreamWithString(writer, 32); } curOffset = writer.BaseStream.Position; } // Image data pass for (int i = 0; i < imgData.Count; i++) { writer.Seek((int)start + (i * 32) + 60, System.IO.SeekOrigin.Begin); // offset of the image header + 32 bytes for the section's header + 28 bytes into the image header for image data offset writer.Write((int)(curOffset - start) - (32 + i * 32)); // Offsets are relative to the start of the image header writer.Seek(0, System.IO.SeekOrigin.End); writer.Write(imgData[i].Item1); curOffset = writer.BaseStream.Position; } writer.Seek((int)start + 16, System.IO.SeekOrigin.Begin); writer.Write((int)(curOffset - start)); writer.Seek((int)curOffset, System.IO.SeekOrigin.Begin); NameTableIO.Write(writer, names); StreamUtility.PadStreamWithString(writer, 32); long end = writer.BaseStream.Position; long length = (end - start); writer.Seek((int)start + 4, System.IO.SeekOrigin.Begin); writer.Write((int)length); writer.Seek((int)end, System.IO.SeekOrigin.Begin); }