/// <summary> /// Write a GSprite with specified Binary Writer. /// </summary> public void Write(DhBinaryWriter bw) { // Write GSprite's Unknown 1. bw.WriteS16(Unknown1); // Write GSprite's Unknown 2. bw.WriteS16(Unknown2); // Write GSprite's RGBA. bw.WriteS32(RGBA); // Loop through GSprite's points. for (int i = 0; i < Points.Count; i++) { // Write the current point. Points[i].Write(bw); } // Loop through the GSprite's Unknown 3 values. for (int i = 0; i < Unknown3.Length; i++) { // Write the current GSprite's Unknown 3 value. bw.WriteS32(Unknown3[i]); } // Write GSprite's Unknown 4. bw.WriteF32(Unknown4); // Write GSprite's Unknown 5. bw.WriteF32(Unknown5); // Write GSprite's Unknown 6. bw.WriteS32(Unknown6); }
/// <summary> /// Write a single entry to stream. /// </summary> /// <param name="bw">Binary Writer to use.</param> public void Write(DhBinaryWriter bw) { // Write Id. bw.WriteU32(Id); // Write Gain. bw.WriteF32(Gain); // Write Delay / Length. bw.WriteF32(Delay); // Write Pitch. bw.WriteF32(Pitch); // Write Unknown 1. bw.WriteS32(Unknown1); // Write Balance. bw.Write(Balance); // Write Unknown 3. bw.Write(Unknown2); // Write Unknown 4. bw.Write(Unknown3); // Write Unknown 5. bw.Write(Unknown4); // Write Padding 2. bw.WriteU32s(Padding); }
/// <summary> /// Write a single texture coordinate with specified Binary Writer. /// </summary> /// <param name="bw">Binary Writer to use.</param> public void Write(DhBinaryWriter bw) { // Write X-Coordinate. bw.WriteF32(X); // Write Y-Coordinate. bw.WriteF32(Y); }
/// <summary> /// Write a SpritePoint with specified Binary Writer. /// </summary> public void Write(DhBinaryWriter bw) { // Write SpritePoint's X Position. bw.WriteF32(Position.X); // Write SpritePoint's Y Position. bw.WriteF32(Position.Y); // Read SpritePoint's Unknown 1. bw.WriteS32(Unknown1); }
/// <summary> /// Read a single keyframe. /// </summary> /// <param name="bw">The binary writer to write with.</param> public void Write(DhBinaryWriter bw) { // Write time. bw.WriteF32(Time); // Write keyframe data. bw.WriteF32s(Data.ToArray()); }
/// <summary> /// Write a PrmEntry with specified Binary Writer. /// </summary> /// <param name="bw">Binary Writer to use.</param> public void Write(DhBinaryWriter bw) { // Write Hash. bw.WriteU16(Hash); // Write NameLength. bw.WriteU16(NameLength); // Write Name. bw.WriteStr(Name); // Write ValueLength. bw.WriteU32(ValueLength); // Check Type. switch (Type) { case PrmType.BYTE: // Write Value as a byte. bw.Write((byte)Value); break; case PrmType.SHORT: // Write Value as a short. bw.WriteS16((short)Value); break; case PrmType.INT: // Write Value as a int. bw.WriteS32((int)Value); break; case PrmType.FLOAT: // Write Value as a float. bw.WriteF32((float)Value); break; case PrmType.RGBA: // Write Value as a Clr4. bw.WriteClr4((Clr4)Value); break; case PrmType.VECTOR3: // Write Value as a Vector3. bw.WriteVec3((Vec3)Value); break; default: throw new NotImplementedException("PRM parameter entry type is unknown!"); } }
/// <summary> /// Write a single graph object with BinaryWriter. /// </summary> /// <param name="bw">Binary Writer to use.</param> /// <param name="graphObjectsOffset">Offset to the graph objects.</param> public void Write(DhBinaryWriter bw) { // Write parent graphobject index. bw.WriteS16(ParentIndex); // Write child graphobject index. bw.WriteS16(ChildIndex); // Write next graphobject index. bw.WriteS16(NextIndex); // Write previous graphobject index. bw.WriteS16(PreviousIndex); // Write renderflags. bw.WriteU16((ushort)RenderFlags); // Write unknown 1. bw.WriteU16(Unknown1); // Write scale. bw.WriteVec3(Scale); // Write rotation. bw.WriteVec3(Rotation); // Write position. bw.WriteVec3(Position); // Write bounding box minimum. bw.WriteVec3(BoundingBoxMinimum); // Write bounding box maximum. bw.WriteVec3(BoundingBoxMaximum); // Write bounding sphere radius. bw.WriteF32(BoundingSphereRadius); // Write part count. bw.WriteS16((short)Parts.Count); // Write unknown 3. bw.WriteU16(Unknown3); // Write part offset. (CALCULATED) bw.WriteU32(0); // Write unknown 4. bw.WriteU32s(Unknown4); // Write unknown 4. TODO - Why does demolisher only read file if padding is written twice?? bw.WriteU32s(Unknown4); }
/// <summary> /// Write a single entry to stream. /// Full credits for the 'packing' snippet goes to arookas: /// https://github.com/arookas/jmpman/blob/master/jmpman/jmp.cs /// </summary> /// <param name="bw">Binary Writer to use.</param> public void Write(DhBinaryWriter bw, List <JField> fields) { long currentPosition = bw.Position(); Dictionary <ushort, uint> buffer = new Dictionary <ushort, uint>(fields.Count); for (int i = 0; i < fields.Count; i++) { bw.Sail(fields[i].Offset); switch (fields[i].Type) { case JFieldType.INTEGER: int value = Convert.ToInt32(Values.Values.ElementAt(i)); if (fields[i].Bitmask == 0xFFFFFFFF) { // not packed, write data directly. bw.WriteS32((value)); } else { if (!buffer.ContainsKey(fields[i].Offset)) { buffer[fields[i].Offset] = 0u; } // packed, add data to buffer. buffer[fields[i].Offset] |= ((uint)(value << fields[i].Shift) & fields[i].Bitmask); } break; case JFieldType.STRING: bw.WriteFixedStr(Convert.ToString(Values.Values.ElementAt(i)), 32); break; case JFieldType.FLOAT: bw.WriteF32(Convert.ToSingle(Values.Values.ElementAt(i))); break; default: throw new InvalidDataException($"{fields[i].Type} is not a valid jmp entry type!"); } foreach (var data in buffer) { bw.Goto(currentPosition + data.Key); bw.WriteU32(data.Value); } bw.Goto(currentPosition); } }
/// <summary> /// Write a single triangle data entry with specified Binary Writer. /// </summary> /// <param name="bw">Binary Writer to use.</param> public void Write(DhBinaryWriter bw) { // Write Vertex Indices. bw.WriteS16s(VertexIndices); // Write Normal Index. bw.WriteS16(NormalIndex); // Write Edge Tangent Indices. bw.WriteS16s(EdgeTangentIndices); // Write Plane Point Index. bw.WriteS16(PlanePointIndex); // Write PlaneD Value. bw.WriteF32(PlaneDValue); // Write Unknown 1. bw.WriteS16(Unknown1); // Write Unknown 2. bw.WriteS16(Unknown2); }
/// <summary> /// Write a single entry to stream. /// Credits for the 'packing' snippet goes to arookas: /// https://github.com/arookas/jmpman/blob/master/jmpman/jmp.cs /// </summary> /// <param name="bw">Binary Writer to use.</param> public void Write(DhBinaryWriter bw, List <JField> fields) { // Save the current position. long currentPosition = bw.Position(); // Define a buffer to hold packed int values. Dictionary <ushort, uint> buffer = new Dictionary <ushort, uint>(fields.Count); // Loop through each value in the entry. for (int i = 0; i < fields.Count; i++) { // Seek from the current position to value's offset in the entry. bw.Sail(fields[i].Offset); // Check which type the current value is. switch (fields[i].Type) { case JFieldType.INTEGER: // Write the value as a integer. TODO: Add pack values. int value = int.Parse(Values[i].ToString()); // Check if current field has a bitmask. if (fields[i].Bitmask == 0xFFFFFFFF) { // Value is not packed, write data directly. bw.WriteS32((value)); } else { // Value is packed, data will be added to the buffer. if (!buffer.ContainsKey(fields[i].Offset)) { // Since no key exists yet, create one. buffer[fields[i].Offset] = 0u; } // Add the packet int value to the buffer. buffer[fields[i].Offset] |= ((uint)(value << fields[i].Shift) & fields[i].Bitmask); } break; case JFieldType.STRING: // Write the value as a string. bw.WriteStr32(Values[i].ToString()); break; case JFieldType.FLOAT: // Write the value as a float32. bw.WriteF32(float.Parse(Values[i].ToString())); break; default: // Something went horribly wrong. throw new InvalidDataException(); } // Write out the packed int's buffer. foreach (var data in buffer) { // bw.Goto(currentPosition + data.Key); // Write the packed int value. bw.WriteU32(data.Value); } // Seek back to the position we saved earlier. bw.Goto(currentPosition); } }