internal void WriteValueIDs(BinaryWriterEx bw, GPGame game, int groupIndex, int valueIDsOffset) { for (int i = 0; i < Params.Count; i++) { Params[i].WriteValueIDs(bw, game, groupIndex, i, valueIDsOffset); } }
/// <summary> /// Creates a new empty GPARAM formatted for Sekiro. /// </summary> public GPARAM() { Game = GPGame.Sekiro; Groups = new List <Group>(); UnkBlock2 = new byte[0]; Unk3s = new List <Unk3>(); }
internal void WriteParamHeaders(BinaryWriterEx bw, GPGame game, int groupindex, int paramHeadersOffset) { for (int i = 0; i < Params.Count; i++) { Params[i].WriteParamHeader(bw, game, groupindex, i, paramHeadersOffset); } }
internal Group(BinaryReaderEx br, GPGame game, int index, Offsets offsets) { int groupHeaderOffset = br.ReadInt32(); br.StepIn(offsets.GroupHeaders + groupHeaderOffset); { int paramCount = br.ReadInt32(); int paramHeaderOffsetsOffset = br.ReadInt32(); if (game == GPGame.DarkSouls2) { Name1 = br.ReadShiftJIS(); } else { Name1 = br.ReadUTF16(); Name2 = br.ReadUTF16(); } br.StepIn(offsets.ParamHeaderOffsets + paramHeaderOffsetsOffset); { Params = new List <Param>(paramCount); for (int i = 0; i < paramCount; i++) { Params.Add(new Param(br, game, offsets)); } } br.StepOut(); } br.StepOut(); Comments = new List <string>(); }
internal void WriteHeader(BinaryWriterEx bw, GPGame game, int index) { bw.WriteInt32(GroupIndex); bw.WriteInt32(ValueIDs.Count); bw.ReserveInt32($"Unk3ValueIDsOffset{index}"); if (game == GPGame.Sekiro) { bw.WriteInt32(Unk0C); } }
internal void WriteValues(BinaryWriterEx bw, GPGame game, int index, int unk3ValueIDsOffset) { if (ValueIDs.Count == 0) { bw.FillInt32($"Unk3ValueIDsOffset{index}", 0); } else { bw.FillInt32($"Unk3ValueIDsOffset{index}", (int)bw.Position - unk3ValueIDsOffset); bw.WriteInt32s(ValueIDs); } }
internal void WriteValueIDs(BinaryWriterEx bw, GPGame game, int groupIndex, int paramIndex, int valueIDsOffset) { bw.FillInt32($"ValueIDsOffset{groupIndex}:{paramIndex}", (int)bw.Position - valueIDsOffset); for (int i = 0; i < ValueIDs.Count; i++) { bw.WriteInt32(ValueIDs[i]); if (game == GPGame.Sekiro) { bw.WriteSingle(UnkFloats[i]); } } }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; // Don't @ me. br.AssertASCII("f\0i\0l\0t\0"); Game = br.ReadEnum32 <GPGame>(); Unk0C = br.ReadInt32(); int groupCount = br.ReadInt32(); Unk14 = br.ReadInt32(); // Header size or group header headers offset, you decide br.AssertInt32(Game == GPGame.DarkSouls3 ? 0x50 : 0x54); Offsets offsets; offsets.GroupHeaders = br.ReadInt32(); offsets.ParamHeaderOffsets = br.ReadInt32(); offsets.ParamHeaders = br.ReadInt32(); offsets.Values = br.ReadInt32(); offsets.ValueIDs = br.ReadInt32(); offsets.Unk2 = br.ReadInt32(); int unk3Count = br.ReadInt32(); offsets.Unk3 = br.ReadInt32(); offsets.Unk3ValueIDs = br.ReadInt32(); br.AssertInt32(0); offsets.CommentOffsetsOffsets = br.ReadInt32(); offsets.CommentOffsets = br.ReadInt32(); offsets.Comments = br.ReadInt32(); if (Game == GPGame.Sekiro) { Unk50 = br.ReadSingle(); } Groups = new List <Group>(groupCount); for (int i = 0; i < groupCount; i++) { Groups.Add(new Group(br, Game, i, offsets)); } UnkBlock2 = br.GetBytes(offsets.Unk2, offsets.Unk3 - offsets.Unk2); br.Position = offsets.Unk3; Unk3s = new List <Unk3>(unk3Count); for (int i = 0; i < unk3Count; i++) { Unk3s.Add(new Unk3(br, Game, offsets)); } }
internal Unk3(BinaryReaderEx br, GPGame game, Offsets offsets) { GroupIndex = br.ReadInt32(); int count = br.ReadInt32(); uint valueIDsOffset = br.ReadUInt32(); if (game == GPGame.Sekiro) { Unk0C = br.ReadInt32(); } ValueIDs = new List <int>(br.GetInt32s(offsets.Unk3ValueIDs + valueIDsOffset, count)); }
internal void WriteHeader(BinaryWriterEx bw, GPGame game, int groupIndex, int groupHeadersOffset) { bw.FillInt32($"GroupHeaderOffset{groupIndex}", (int)bw.Position - groupHeadersOffset); bw.WriteInt32(Params.Count); bw.ReserveInt32($"ParamHeaderOffsetsOffset{groupIndex}"); if (game == GPGame.DarkSouls2) { bw.WriteShiftJIS(Name1, true); } else { bw.WriteUTF16(Name1, true); bw.WriteUTF16(Name2, true); } bw.Pad(4); }
internal Group(BinaryReaderEx br, GPGame game, int index, Offsets offsets) { int groupHeaderOffset = br.ReadInt32(); br.StepIn(offsets.GroupHeaders + groupHeaderOffset); int paramCount = br.ReadInt32(); int paramHeaderOffsetsOffset = br.ReadInt32(); Name1 = br.ReadUTF16(); Name2 = br.ReadUTF16(); br.StepIn(offsets.ParamHeaderOffsets + paramHeaderOffsetsOffset); { Params = new List <Param>(paramCount); for (int i = 0; i < paramCount; i++) { Params.Add(new Param(br, game, offsets)); } } br.StepOut(); if (Params.Count > 0) { int commentCount = Params[0].Values.Count; Comments = new List <string>(commentCount); int commentOffsetsOffset = br.GetInt32(offsets.CommentOffsetsOffsets + index * 4); br.StepIn(offsets.CommentOffsets + commentOffsetsOffset); { for (int i = 0; i < commentCount; i++) { int commentOffset = br.ReadInt32(); Comments.Add(br.GetUTF16(offsets.Comments + commentOffset)); } } br.StepOut(); } else { Comments = new List <string>(); } br.StepOut(); }
internal void WriteParamHeader(BinaryWriterEx bw, GPGame game, int groupIndex, int paramIndex, int paramHeadersOffset) { bw.FillInt32($"ParamHeaderOffset{groupIndex}:{paramIndex}", (int)bw.Position - paramHeadersOffset); bw.ReserveInt32($"ValuesOffset{groupIndex}:{paramIndex}"); bw.ReserveInt32($"ValueIDsOffset{groupIndex}:{paramIndex}"); bw.WriteByte((byte)Type); bw.WriteByte((byte)Values.Count); bw.WriteByte(0); bw.WriteByte(0); if (game == GPGame.DarkSouls2) { bw.WriteShiftJIS(Name1, true); } else { bw.WriteUTF16(Name1, true); bw.WriteUTF16(Name2, true); } bw.Pad(4); }
internal override void Read(BinaryReaderEx br) { br.BigEndian = false; // Don't @ me. if (br.AssertASCII("filt", "f\0i\0") == "f\0i\0") { br.AssertASCII("l\0t\0"); } Game = br.ReadEnum32 <GPGame>(); br.AssertByte(0); Unk0D = br.ReadBoolean(); br.AssertInt16(0); int groupCount = br.ReadInt32(); Unk14 = br.ReadInt32(); // Header size or group header headers offset, you decide br.AssertInt32(0x40, 0x50, 0x54); Offsets offsets = default; offsets.GroupHeaders = br.ReadInt32(); offsets.ParamHeaderOffsets = br.ReadInt32(); offsets.ParamHeaders = br.ReadInt32(); offsets.Values = br.ReadInt32(); offsets.ValueIDs = br.ReadInt32(); offsets.Unk2 = br.ReadInt32(); int unk3Count = br.ReadInt32(); offsets.Unk3 = br.ReadInt32(); offsets.Unk3ValueIDs = br.ReadInt32(); br.AssertInt32(0); if (Game == GPGame.DarkSouls3 || Game == GPGame.Sekiro) { offsets.CommentOffsetsOffsets = br.ReadInt32(); offsets.CommentOffsets = br.ReadInt32(); offsets.Comments = br.ReadInt32(); } if (Game == GPGame.Sekiro) { Unk50 = br.ReadSingle(); } Groups = new List <Group>(groupCount); for (int i = 0; i < groupCount; i++) { Groups.Add(new Group(br, Game, i, offsets)); } UnkBlock2 = br.GetBytes(offsets.Unk2, offsets.Unk3 - offsets.Unk2); br.Position = offsets.Unk3; Unk3s = new List <Unk3>(unk3Count); for (int i = 0; i < unk3Count; i++) { Unk3s.Add(new Unk3(br, Game, offsets)); } if (Game == GPGame.DarkSouls3 || Game == GPGame.Sekiro) { int[] commentOffsetsOffsets = br.GetInt32s(offsets.CommentOffsetsOffsets, groupCount); int commentOffsetsLength = offsets.Comments - offsets.CommentOffsets; for (int i = 0; i < groupCount; i++) { int commentCount; if (i == groupCount - 1) { commentCount = (commentOffsetsLength - commentOffsetsOffsets[i]) / 4; } else { commentCount = (commentOffsetsOffsets[i + 1] - commentOffsetsOffsets[i]) / 4; } br.Position = offsets.CommentOffsets + commentOffsetsOffsets[i]; for (int j = 0; j < commentCount; j++) { int commentOffset = br.ReadInt32(); string comment = br.GetUTF16(offsets.Comments + commentOffset); Groups[i].Comments.Add(comment); } } } }
internal Param(BinaryReaderEx br, GPGame game, Offsets offsets) { int paramHeaderOffset = br.ReadInt32(); br.StepIn(offsets.ParamHeaders + paramHeaderOffset); { int valuesOffset = br.ReadInt32(); int valueIDsOffset = br.ReadInt32(); Type = br.ReadEnum8 <ParamType>(); byte valueCount = br.ReadByte(); br.AssertByte(0); br.AssertByte(0); if (Type == ParamType.Byte && valueCount > 1) { throw new Exception("Notify TKGP so he can look into this, please."); } if (game == GPGame.DarkSouls2) { Name1 = br.ReadShiftJIS(); } else { Name1 = br.ReadUTF16(); Name2 = br.ReadUTF16(); } br.StepIn(offsets.Values + valuesOffset); { Values = new List <object>(valueCount); for (int i = 0; i < valueCount; i++) { switch (Type) { case ParamType.Byte: Values.Add(br.ReadByte()); break; case ParamType.Short: Values.Add(br.ReadInt16()); break; case ParamType.IntA: Values.Add(br.ReadInt32()); break; case ParamType.BoolA: Values.Add(br.ReadBoolean()); break; case ParamType.IntB: Values.Add(br.ReadInt32()); break; case ParamType.Float: Values.Add(br.ReadSingle()); break; case ParamType.BoolB: Values.Add(br.ReadBoolean()); break; case ParamType.Float2: Values.Add(br.ReadVector2()); br.AssertInt32(0); br.AssertInt32(0); break; case ParamType.Float3: Values.Add(br.ReadVector3()); br.AssertInt32(0); break; case ParamType.Float4: Values.Add(br.ReadVector4()); break; case ParamType.Byte4: Values.Add(br.ReadBytes(4)); break; } } } br.StepOut(); br.StepIn(offsets.ValueIDs + valueIDsOffset); { ValueIDs = new List <int>(valueCount); if (game == GPGame.Sekiro) { UnkFloats = new List <float>(valueCount); } else { UnkFloats = null; } for (int i = 0; i < valueCount; i++) { ValueIDs.Add(br.ReadInt32()); if (game == GPGame.Sekiro) { UnkFloats.Add(br.ReadSingle()); } } } br.StepOut(); } br.StepOut(); }