/// <summary> /// Read a PrmEntry from PRM. /// </summary> /// <param name="br">Binary Reader to use.</param> public PrmEntry(DhBinaryReader br) { // Read Hash. Hash = br.ReadU16(); // Read NameLength. NameLength = br.ReadU16(); // Read Name. Name = br.ReadStr(NameLength); // Read ValueLength. ValueLength = br.ReadU32(); // Resolve Type from Hash. Type = PRMUtils.HashToType(Hash); // Check Type. switch (Type) { case PrmType.BYTE: // Read Value as a byte. Value = br.Read(); break; case PrmType.SHORT: // Read Value as a short. Value = br.ReadS16(); break; case PrmType.INT: // Read Value as a int. Value = br.ReadS32(); break; case PrmType.FLOAT: // Read Value as a float. Value = br.ReadF32(); break; case PrmType.RGBA: // Read Value as a RGBA. Value = new Color4(br.Read(), br.Read(), br.Read(), br.Read()); break; case PrmType.VECTOR3: // Read Value as a Vector3. Value = new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()); break; default: throw new NotImplementedException("Parameter entry type is unknown!"); } }
/// <summary> /// Read a single entry from BAS. /// </summary> /// <param name="br">Binary Reader to use.</param> public BasEntry(DhBinaryReader br) { // Read Id. Id = br.ReadU32(); // Read Gain. Gain = br.ReadF32(); // Read Delay / Length. Delay = br.ReadF32(); // Read Pitch. Pitch = br.ReadF32(); // Read Unknown 1. Unknown1 = br.ReadS32(); // Read Balance. Balance = br.Read(); // Read Unknown 2. Unknown2 = br.Read(); // Read Unknown 3. Unknown3 = br.Read(); // Read Unknown 4. Unknown4 = br.Read(); // Read Padding. Padding = br.ReadU32s(2); }
/// <summary> /// Read a SpritePoint from GEB. /// </summary> /// <param name="br">Binary Reader to use.</param> public SpritePoint(DhBinaryReader br) { // Read SpritePoint's Position. Position = new Vector2(br.ReadF32(), br.ReadF32()); // Read SpritePoint's Unknown 1. Unknown1 = br.ReadS32(); }
/// <summary> /// Read a single texture coordinate from BIN. /// </summary> /// <param name="br">Binary Reader to use.</param> public BinTextureCoordinate(DhBinaryReader br) { // Read X-Coordinate. X = br.ReadF32(); // Read Y-Coordinate. Y = br.ReadF32(); }
/// <summary> /// Read a single entry from JMP. /// </summary> /// <param name="br">Binary Reader to use.</param> /// <param name="fields">List of fields in JMP.</param> public JEntry(DhBinaryReader br, List <JField> fields) { long currentPosition = br.Position(); Values = new Dictionary <string, object>(); for (int i = 0; i < fields.Count; i++) { br.Sail(fields[i].Offset); object value; switch (fields[i].Type) { case JFieldType.INTEGER: value = ((br.ReadS32() & fields[i].Bitmask) >> fields[i].Shift); break; case JFieldType.STRING: value = br.ReadFixedStr(32); break; case JFieldType.FLOAT: value = br.ReadF32(); break; default: throw new InvalidDataException($"{fields[i].Type} is not a valid jmp entry type!"); } Values.Add(fields[i].Name, value); br.Goto(currentPosition); } }
/// <summary> /// Read a single keyframe from TMB. /// </summary> /// <param name="br">The binary reader to read with.</param> /// <param name="dataCount">The amount of floats in this keyframe.</param> public TIMKeyFrame(DhBinaryReader br, ushort dataCount) { // Read time. Time = br.ReadF32(); // Read keyframe data. Data = br.ReadF32s(dataCount - 1).ToList(); }
/// <summary> /// Read a GSprite from GEB. /// </summary> /// <param name="br">Binary Reader to use.</param> public GSprite(DhBinaryReader br) { // Read GSprite's Unknown 1. Unknown1 = br.ReadS16(); // Read GSprite's Unknown 2. Unknown2 = br.ReadS16(); // Read GSprite's RGBA. RGBA = br.ReadS32(); // Define a new list to hold the GSprite's points. Points = new List <SpritePoint>(); // Loop through GSprite's points. for (int i = 0; i < 4; i++) { // Read point and add it to the spritepoint list. Points.Add(new SpritePoint(br)); } // Define a array to hold the unknown values. Unknown3 = new int[10]; // Loop through the unknown values. for (int i = 0; i < Unknown3.Length; i++) { // Read the current unknown value. Unknown3[i] = br.ReadS32(); } // Read GSprite's Unknown 4. Unknown4 = br.ReadF32(); // Read GSprite's Unknown 5. Unknown5 = br.ReadF32(); // Read GSprite's Unknown 6. Unknown6 = br.ReadS32(); }
/// <summary> /// Read a single entry from JMP. /// </summary> /// <param name="br">Binary Reader to use.</param> /// <param name="fields">List of fields in JMP.</param> public JEntry(DhBinaryReader br, List <JField> fields) { // Save the current position. long currentPosition = br.Position(); // Define a new object array to hold entry's values. Values = new object[fields.Count]; // Loop through each field in the JMP. for (int i = 0; i < fields.Count; i++) { // Seek from the current position to value's offset in the entry. br.Sail(fields[i].Offset); // Define a new object to hold our data. object value; // Check which type the current value is. switch (fields[i].Type) { case JFieldType.INTEGER: // Read the data as a integer. value = ((br.ReadS32() & fields[i].Bitmask) >> fields[i].Shift); break; case JFieldType.STRING: // Read the data as a 32-byte long string. value = br.ReadStr32(); break; case JFieldType.FLOAT: // Read the data as a float32. value = br.ReadF32(); break; default: // Something went horribly wrong. throw new InvalidDataException(); } // Set the value of this entry's value's data to the value we just read. Values[i] = value; // Seek back to the position we saved earlier. br.Goto(currentPosition); } }
/// <summary> /// Read a single triangle data entry from MP. /// </summary> /// <param name="br">Binary Reader to use.</param> public MpTriangleData(DhBinaryReader br) { // Define a new array to hold vertex indices. VertexIndices = new short[3]; // Loop through Vertex indices. for (int i = 0; i < 3; i++) { // Read Vertex index and store it in the VertexIndices array. VertexIndices[i] = br.ReadS16(); } // Read Normal Index. NormalIndex = br.ReadS16(); // Define a new array to hold edge tangent indices. EdgeTangentIndices = new short[3]; // Loop through Edge Tangent indices. for (int i = 0; i < 3; i++) { // Read Edge Tangent index and store it in the EdgeTangentIndices array. EdgeTangentIndices[i] = br.ReadS16(); } // Read Unknown 1. Unknown1 = br.ReadS16(); // Read Unknown 2. Unknown2 = br.ReadF32(); // Read Unknown 3. Unknown3 = br.ReadS16(); // Read Unknown 4. Unknown4 = br.ReadS16(); }
/// <summary> /// Reads MP from a stream. /// </summary> /// <param name="stream">The stream containing the MP data.</param> public MP(Stream stream) { // Define a binary reader to read with. DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big); // Read Grid Scale. GridScale = new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()); // Read Minimum Bounds. MinimumBounds = new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()); // Read Axis Lengths. AxisLengths = new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32()); // Define new array to hold offsets. Offsets = new int[7]; // Loop through our offsets. for (int i = 0; i < 7; i++) { // Read offset and store it to the offsets array. Offsets[i] = br.ReadS32(); } // Go to mp's vertex data offset. br.Goto(Offsets[0]); // Calculate amount of vertices. int verticeCount = (Offsets[1] - Offsets[0]) / 12; // Define new list to hold vertices. Vertices = new List <Vector3>(); // Loop through vertices. for (int i = 0; i < verticeCount; i++) { // Read vertex and add it to the vertice list. Vertices.Add(new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32())); } // Go to mp's normals offset. br.Goto(Offsets[1]); // Calculate amount of normals. int normalCount = (Offsets[2] - Offsets[1]) / 12; // Define new list to hold normals. Normals = new List <Vector3>(); // Loop through normals. for (int i = 0; i < verticeCount; i++) { // Read normal and add it to the normal list. Normals.Add(new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32())); } // Go to mp's triangle data offset. br.Goto(Offsets[2]); // Calculate amount of normals. int triangleDataCount = (Offsets[3] - Offsets[2]) / 24; // Define new list to hold normals. TriangleData = new List <MpTriangleData>(); // Loop through normals. for (int i = 0; i < triangleDataCount; i++) { // Read normal and add it to the normal list. TriangleData.Add(new MpTriangleData(br)); } // Go to mp's triangle group offset. br.Goto(Offsets[3]); // TODO: Implement reading Triangle Group data. // Go to mp's grid index offset. br.Goto(Offsets[4]); // Calculate amount of grid index entries. int gridIndexCount = (Offsets[4] - Offsets[3]) / 8; // Define new list to hold grid indices. GridIndices = new List <MpGridIndex>(); // Loop through grid indices. for (int i = 0; i < gridIndexCount; i++) { // Read grid index and add it to the grid indices list. GridIndices.Add(new MpGridIndex(br)); } // Go to mp's unknown offset. br.Goto(Offsets[5]); // TODO: Implement reading Unknown data. }
/// <summary> /// Read a single graph object from BIN. /// </summary> /// <param name="br">Binary Reader to use.</param> /// <param name="graphObjectOffset">Offset to the graph objects.</param> public GraphObject(DhBinaryReader br, uint graphObjectOffset) // 112 bytes long { // Read Parent Index. ParentIndex = br.ReadS16(); // Read Child Index. ChildIndex = br.ReadS16(); // Read Next Index. NextIndex = br.ReadS16(); // Read Previous Index. PreviousIndex = br.ReadS16(); // Read Render Flags. RenderFlags = (GraphObjectRenderFlags)br.ReadU16(); // Unknown 1. (Padding?) Unknown1 = br.ReadU16(); // Read Scale. Scale = br.ReadVec3(); // Read Rotation. Rotation = br.ReadVec3(); // Read Position Position = br.ReadVec3(); // Read Bounding Box Minimum. BoundingBoxMinimum = br.ReadVec3(); // Read Bounding Box Maximum. BoundingBoxMaximum = br.ReadVec3(); // Read Bounding Sphere Radius. BoundingSphereRadius = br.ReadF32(); // Read Parent Index. PartCount = br.ReadS16(); // Unknown 3. (Padding?) Unknown3 = br.ReadU16(); // Read Parent Index. PartOffset = br.ReadS32(); // Unknown 4. (Padding?) Unknown4 = br.ReadU32s(7); // Initialize a new list to hold parts. Parts = new List <BinGraphObjectPart>(); // Offset to continue reading from. long currentPosition = br.Position(); // Goto graphobject's parts. br.Goto(graphObjectOffset + PartOffset); // Loop through parts. for (int i = 0; i < PartCount; i++) { // Read part and add it to the list of parts. Parts.Add(new BinGraphObjectPart(br)); } // Go back to return offset we saved earlier. br.Goto(currentPosition); }
/// <summary> /// Reads BIN from a stream. /// </summary> /// <param name="stream">The stream containing the BIN data.</param> public BIN(Stream stream) { // Define a binary reader to read with. DhBinaryReader br = new DhBinaryReader(stream, DhEndian.Big); // Read bin version. Version = br.Read(); // Make sure the bin version is either 0x01 or 0x02. if (Version == 0x00 || Version > 0x02) { throw new Exception(string.Format("{0} is not a valid bin version!", Version.ToString())); } // Read bin model name. ModelName = br.ReadStr(11).Trim('\0'); // Define a new list to hold the bin's offsets. Offsets = new List <uint>(); // Loop through the bin's offsets. for (int i = 0; i < 21; i++) { // Read offset and add it to the offsets list. Offsets.Add(br.ReadU32()); } // Go to the bin textures offset. br.Goto(Offsets[0]); // Define a new list to hold the bin's textures. Textures = new List <BinTexture>(); // Loop through bin's textures. TODO: This is static for now, add automatic texture count. for (int i = 0; i < 3; i++) { // Read texture and add it to the textures list. Textures.Add(new BinTexture(br, Offsets[0])); } // Go to the bin materials offset. br.Goto(Offsets[1]); // Define a new list to hold the bin's materials. Materials = new List <BinMaterial>(); // Loop through bin's materials. TODO: This is static for now, add automatic material count. for (int i = 0; i < 3; i++) { // Read texture and add it to the materials list. Materials.Add(new BinMaterial(br)); } // Go to the bin positions offset. br.Goto(Offsets[2]); // Define a new list to hold the bin's positions. Positions = new List <Vector3>(); // Loop through bin's positions. TODO: Fix this; This is a pretty shitty way to calculate amount of bin positions ... for (int i = 0; i < ((Math.Floor((decimal)(Offsets[3] - Offsets[2])) / 6) - 1); i++) { // Skip 6 bytes to "simulate" reading a bin position. br.Skip(6); // Make sure the currenet position has not passed the normals offset. if (!(br.Position() > Offsets[3])) { // Go back 6 bytes as we just "simulated" to read a bin position. br.Goto(br.Position() - 6); // Read a position and add it to the positions list. Positions.Add(new Vector3(br.ReadF16(), br.ReadF16(), br.ReadF16())); } } // Go to the bin normals offset. br.Goto(Offsets[3]); // Define a new list to hold the bin's normals. Normals = new List <Vector3>(); // Loop through bin's normals. TODO: This is static for now, add automatic normal count. for (int i = 0; i < 69; i++) { // Read a normal and add it to the normals list. Normals.Add(new Vector3(br.ReadF32(), br.ReadF32(), br.ReadF32())); } // Go to the bin texture coordinates offset. br.Goto(Offsets[6]); // Define a new list to hold the bin's texture coordinates. TextureCoordinates = new List <BinTextureCoordinate>(); // Loop through bin's texture coordinates. TODO: This is static for now, add automatic texture coordinates count. for (int i = 0; i < 72; i++) { // Read a bin texture coordinates and add it to the texture coordinates list. TextureCoordinates.Add(new BinTextureCoordinate(br)); } // Go to the bin shaders offset. br.Goto(Offsets[10]); // Define a new list to hold the bin's shaders. Shaders = new List <BinShader>(); // Loop through bin's shaders. TODO: This is static for now, add automatic shader count. for (int i = 0; i < 3; i++) { // Read a bin shader and add it to the shaders list. Shaders.Add(new BinShader(br)); } // Go to the bin batches offset. br.Goto(Offsets[11]); // Define a new list to hold the bin's batches. Batches = new List <BinBatch>(); // Loop through bin's batches. TODO: This is static for now, add automatic batch count. for (int i = 0; i < 2; i++) { // Read a bin batch and add it to the batches list. Batches.Add(new BinBatch(br, Offsets[11])); } }