public override void Save(ExtendedBinaryWriter writer) { ManualCount = 0; var strings = new List <string>(); writer.WriteSignature("STSC"); writer.AddOffset("EntryPosition"); writer.Write(Version); switch (Version) { case 4: // Date A Live: Twin Edition Rio Reincarnation (PSV) writer.Write((ushort)ScriptID); break; case 7: // Date A Live: Rio Reincarnation (PC) writer.WriteSignature(ScriptName); writer.WriteNulls((uint)(0x20 - ScriptName.Length)); // Pad Script Name writer.Write(0x000607E3); writer.Write((short)0x06); writer.Write((short)0x0A); writer.Write((short)0x06); writer.Write((short)0x17); writer.Write(ScriptID); break; } writer.FillInOffset("EntryPosition"); foreach (var instruction in Instructions) { writer.Write((byte)STSCInstructions.DALRRInstructions.FindIndex(t => t?.Name == instruction.Name)); instruction.Write(writer, ref ManualCount, strings); } // Write String Table for (int i = 0; i < strings.Count; ++i) { writer.FillInOffset($"Strings_{i}"); writer.WriteNullTerminatedString(strings[i]); } writer.FixPadding(0x04); WriteStage1(writer); WriteStage2(writer); WriteStage3(writer); WriteStage4(writer); WriteStage5(writer); WriteStage6(writer); WriteStage7(writer); WriteStage8(writer); WriteStage9(writer); // Older versions may not include art books and drama CDs if (Version == 7) { WriteStage10(writer); WriteStage11(writer); } writer.FixPadding(0x10); }
/// <summary> /// ArtBook Pages /// </summary> public void WriteStage10(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_9l", true, false); int i = 0; foreach (var entry in _artBookPages) { writer.AddOffset($"PagePathThumbnail{i}"); writer.AddOffset($"PagePathData{i}"); writer.AddOffset($"Name{i}"); writer.Write(entry.ID); writer.Write((short)entry.GameID); writer.Write(entry.Page); ++i; } writer.FillInOffset("Manual_Ptr_9h", true, false); i = 0; foreach (var entry in _artBookPages) { writer.FillInOffset($"PagePathThumbnail{i}"); writer.WriteNullTerminatedString(entry.PagePathThumbnail); writer.FillInOffset($"PagePathData{i}"); writer.WriteNullTerminatedString(entry.PagePathData); writer.FillInOffset($"Name{i}"); writer.WriteNullTerminatedString(entry.Name); ++i; } writer.FixPadding(0x4); }
/// <summary> /// Voices /// </summary> public void WriteStage8(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_7l", true, false); int i = 0; foreach (var entry in _voices) { writer.AddOffset($"UnknownName{i}"); writer.AddOffset($"KnownName{i}"); writer.AddOffset($"PreferedName{i}"); writer.Write(entry.ID); ++i; } writer.FillInOffset("Manual_Ptr_7h", true, false); i = 0; foreach (var entry in _voices) { writer.FillInOffset($"UnknownName{i}"); writer.WriteNullTerminatedString(entry.UnknownName); writer.FillInOffset($"KnownName{i}"); writer.WriteNullTerminatedString(entry.KnownName); writer.FillInOffset($"PreferedName{i}"); writer.WriteNullTerminatedString(entry.PreferedName); ++i; } writer.FixPadding(0x4); }
public override void Save(ExtendedBinaryWriter writer) { var strings = new List <string>(); writer.WriteSignature("STSC"); writer.AddOffset("EntryPosition"); writer.Write(0x07); // Version writer.WriteSignature(ScriptName); writer.WriteNulls((uint)(0x20 - ScriptName.Length)); // Pad Script Name writer.Write(0x000507E3); writer.Write((short)0x09); writer.Write((short)0x0D); writer.Write((short)0x19); writer.Write((short)0x0D); writer.Write(ScriptID); writer.FillInOffset("EntryPosition"); foreach (var instruction in Instructions) { writer.Write((byte)STSCInstructions.DALRRInstructions.FindIndex(t => t?.Name == instruction.Name)); instruction.Write(writer, ref ManualCount, strings); } // Write String Table for (int i = 0; i < strings.Count; ++i) { writer.FillInOffset($"Strings_{i}"); writer.WriteNullTerminatedString(strings[i]); } writer.FixPadding(0x10); }
/// <summary> /// Memories /// </summary> public void WriteStage4(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_3l", true, false); int i = 0; foreach (var entry in _memories) { writer.AddOffset($"MemName{i}"); writer.AddOffset($"MemDesc{i}"); writer.Write(entry.ID); writer.Write((byte)entry.GameID); writer.Write((byte)entry.Game); writer.Write((short)0); // Padding ++i; } writer.FillInOffset("Manual_Ptr_3h", true, false); i = 0; foreach (var entry in _memories) { writer.FillInOffset($"MemName{i}"); writer.WriteNullTerminatedString(entry.Name); writer.FillInOffset($"MemDesc{i}"); writer.WriteNullTerminatedString(entry.Description); ++i; } writer.FixPadding(0x4); }
/// <summary> /// Movies /// </summary> public void WriteStage3(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_2l", true, false); int i = 0; foreach (var entry in _movies) { writer.AddOffset($"Name{i}"); writer.AddOffset($"Path{i}"); writer.Write(entry.ID); writer.Write(entry.Unknown4); writer.Write((byte)entry.GameID); writer.Write(entry.Unknown5); ++i; } writer.FillInOffset("Manual_Ptr_2h", true, false); i = 0; foreach (var entry in _movies) { writer.FillInOffset($"Name{i}"); writer.WriteNullTerminatedString(entry.FriendlyName); writer.FillInOffset($"Path{i}"); writer.WriteNullTerminatedString(entry.FilePath); ++i; } writer.FixPadding(0x4); }
public override void Save(ExtendedBinaryWriter writer) { // Height of the character in pixels writer.Write(CharacterHeight); // The amount of characters defined writer.Write(Characters.Count); // Unknown writer.Write(WidthScale); writer.Write(HeightScale); foreach (var entry in Characters) { // Writes the character in UTF-8 in reverse byte order, Not sure why its like this writer.Write(Encoding.UTF8.GetBytes(new[] { entry.Character }).Reverse().ToArray()); // Pads the character to be 4 bytes long writer.FixPadding(); // X position on the texture writer.Write(entry.XScale); // Y position on the texture writer.Write(entry.YScale); // -X render offset writer.Write(entry.Kerning); // Width of the character in pixels writer.Write(entry.Width); } }
/// <summary> /// Druma CD /// </summary> public void WriteStage11(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_10l", true, false); int i = 0; foreach (var entry in _dramaCDs) { writer.AddOffset($"FileName{i}"); writer.AddOffset($"FriendlyName{i}"); writer.AddOffset($"SourceAlbum{i}"); writer.AddOffset($"InternalName{i}"); writer.Write(entry.ID); writer.Write((short)entry.Game); writer.Write(entry.Unknown7); writer.Write(entry.SourceTrackID); writer.Write(entry.Unknown9); ++i; } writer.FillInOffset("Manual_Ptr_10h", true, false); i = 0; foreach (var entry in _dramaCDs) { writer.FillInOffset($"FileName{i}"); writer.WriteNullTerminatedString(entry.FileName); writer.FillInOffset($"FriendlyName{i}"); writer.WriteNullTerminatedString(entry.FriendlyName); writer.FillInOffset($"SourceAlbum{i}"); writer.WriteNullTerminatedString(entry.SourceAlbum); writer.FillInOffset($"InternalName{i}"); writer.WriteNullTerminatedString(entry.InternalName); ++i; } writer.FixPadding(0x4); }
/// <summary> /// Unknown 4 /// </summary> public void WriteStage9(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_8l", true, false); foreach (var entry in _unknown4) { writer.Write(entry.Unknown1); writer.Write(entry.Unknown2); } writer.FillInOffset("Manual_Ptr_8h", true, false); writer.FixPadding(0x4); }
protected void FixPadding(ExtendedBinaryWriter writer, Type t) { uint padding = GetPadding(t); if (padding < 2) { return; } writer.FixPadding(padding); }
/// <summary> /// CGs /// </summary> public void WriteStage2(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_1l", true, false); int i = 0; foreach (var entry in _CGs) { writer.AddOffset($"CGName{i}"); writer.Write(entry.ID); writer.Write(entry.CGID); writer.Write(entry.CGID2); writer.Write(entry.Unknown5); writer.Write(entry.Unknown6); writer.Write(entry.TextureWidth); writer.Write(entry.TextureHeight); writer.Write(entry.Unknown7); writer.Write(entry.Unknown81); writer.Write(entry.Unknown82); writer.Write(entry.Unknown83); writer.Write(entry.Page); writer.Write(entry.FrameCount); writer.Write((byte)entry.GameID); writer.Write(entry.Unknown93); writer.Write(entry.Unknown94); writer.Write(entry.Unknown10); writer.Write(entry.Unknown11); writer.Write(entry.Unknown12); writer.Write(entry.Unknown13); writer.Write(entry.Unknown14); writer.Write(entry.Unknown15); writer.Write(entry.Unknown16); writer.Write(entry.Unknown17); writer.Write(entry.Unknown18); writer.Write(entry.Unknown19); writer.Write(entry.Unknown20); writer.Write(entry.Unknown21); writer.Write(entry.Unknown22); writer.Write(entry.Unknown23); writer.Write(entry.Unknown24); writer.Write(entry.Unknown25); writer.Write(entry.Unknown26); writer.Write(entry.Unknown27); ++i; } writer.FillInOffset("Manual_Ptr_1h", true, false); i = 0; foreach (var entry in _CGs) { writer.FillInOffset($"CGName{i}"); writer.WriteNullTerminatedString(entry.Name); ++i; } writer.FixPadding(0x4); }
public override void Save(ExtendedBinaryWriter writer) { var strings = new List <string>(); writer.WriteSignature("STSC"); writer.AddOffset("EntryPosition"); writer.Write(Version); switch (Version) { case 4: // Date A Live: Twin Edition Rio Reincarnation (PSV) writer.Write((ushort)ScriptID); break; case 7: // Date A Live: Rio Reincarnation (PC) writer.WriteSignature(ScriptName); writer.WriteNulls((uint)(0x20 - ScriptName.Length)); // Pad Script Name writer.Write(0x000507E3); writer.Write((short)0x09); writer.Write((short)0x0D); writer.Write((short)0x19); writer.Write((short)0x0D); writer.Write(ScriptID); break; } writer.FillInOffset("EntryPosition"); foreach (var instruction in Instructions) { writer.Write((byte)STSCInstructions.DALRRInstructions.FindIndex(t => t?.Name == instruction.Name)); instruction.Write(writer, ref ManualCount, strings); } // Write String Table Dictionary <string, uint> writtenStrings = new Dictionary <string, uint>(); for (int i = 0; i < strings.Count; ++i) { if (!writer.HasOffset($"Strings_{i}")) { continue; } if (writtenStrings.ContainsKey(strings[i])) { writer.FillInOffset($"Strings_{i}", writtenStrings[strings[i]]); continue; } writer.FillInOffset($"Strings_{i}"); writtenStrings.Add(strings[i], (uint)writer.BaseStream.Position); writer.WriteNullTerminatedString(strings[i]); } writer.FixPadding(0x10); }
/// <summary> /// System Text /// </summary> public void WriteStage1(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_0l", true, false); for (int i = 0; i < _systemText.Count; ++i) { writer.AddOffset($"Stage1_{i}"); } writer.FillInOffset("Manual_Ptr_0h", true, false); for (int i = 0; i < _systemText.Count; ++i) { writer.FillInOffset($"Stage1_{i}"); writer.WriteNullTerminatedString(_systemText.ElementAt(i)); } writer.FixPadding(0x4); }
public void Write(ExtendedBinaryWriter writer, string offsetSuffix = "") { writer.AddOffset($"texNameOffset{offsetSuffix}"); writer.Write(TexFlags); writer.AddOffset($"texTypeOffset{offsetSuffix}"); // Texture Name writer.FillInOffset($"texNameOffset{offsetSuffix}", false, false); writer.WriteNullTerminatedString(TextureName); // Texture Type writer.FillInOffset($"texTypeOffset{offsetSuffix}", false, false); writer.WriteNullTerminatedString(Type); writer.FixPadding(4); }
public void Write(ExtendedBinaryWriter writer) { // Texture Offsets uint textureCount = (uint)textures.Count; writer.AddOffsetTable("texture", textureCount); // Texture Names for (int i = 0; i < textureCount; ++i) { writer.FillInOffset($"texture_{i}", false, false); writer.WriteNullTerminatedString(textures[i].Name); } writer.FixPadding(4); }
public int Save(Stream fileStream, uint?sizeLimit, int startIndex = 0) { // Header var files = GetFiles(false); var writer = new ExtendedBinaryWriter(fileStream, Encoding.ASCII, false); writer.Write(Sig1); writer.Write(Sig2); writer.Write(Sig3); writer.Write(Padding); // The absolute smallest an archive with a header and one // valid file entry can be is 37 bytes. if (sizeLimit.HasValue && sizeLimit < 37) { throw new ArgumentOutOfRangeException("sizeLimit", sizeLimit, "The sizeLimit argument must at least be greater than 36."); } // Data for (int i = startIndex; i < files.Count; ++i) { var file = files[i]; writer.Offset = (uint)fileStream.Position; if (sizeLimit.HasValue && i > startIndex && fileStream.Position + MinFileEntrySize + file.Data.Length > sizeLimit) { return(i); } writer.AddOffset("dataEndOffset"); writer.Write((uint)file.Data.LongLength); writer.AddOffset("dataStartOffset"); writer.WriteNulls(8); // TODO: Figure out what unknown1 and unknown2 are. writer.WriteNullTerminatedString(file.Name); writer.FixPadding(Padding); writer.FillInOffset("dataStartOffset", false); writer.Write(file.Data); writer.FillInOffset("dataEndOffset", false); } return(-1); }
/// <summary> /// Characters /// </summary> public void WriteStage5(ExtendedBinaryWriter writer) { writer.FillInOffset("Manual_Ptr_4l", true, false); int i = 0; foreach (var entry in _characters) { writer.AddOffset($"Name{i}"); writer.Write(entry.ID); ++i; } writer.FillInOffset("Manual_Ptr_4h", true, false); i = 0; foreach (var entry in _characters) { writer.FillInOffset($"Name{i}"); writer.WriteNullTerminatedString(entry.FriendlyName); ++i; } writer.FixPadding(0x4); }
public override void Save(ExtendedBinaryWriter writer) { // Loads all files into memory if not already // This is needed to ensure the reading stream is closed Preload(); // ZLIB Compression Stream mainStream = null; if (Compress) { mainStream = writer.StartDeflateEncapsulation(); } // Filename Section // Address of the Filename section long sectionPosition = writer.BaseStream.Position; writer.WriteDALSignature("Filename", UseSmallSig); writer.AddOffset("SectionSize"); // Allocates space for all the file name pointers foreach (var entry in FileEntries) { writer.AddOffset(entry.FileName); } // Fills in all the file names foreach (var entry in FileEntries) { // Fill in the address and write the file name (including paths) writer.FillInOffset(entry.FileName, (uint)(writer.BaseStream.Position - (UseSmallSig ? 0xC : 0x18))); writer.WriteNullTerminatedString(entry.FileName); } // Fills in the size of the Filename section writer.FillInOffset("SectionSize"); // Realigns the writer writer.FixPadding(UseSmallSig ? 0x04u : 0x08u); // Pack Section // Address to the Pack section sectionPosition = writer.BaseStream.Position; writer.WriteDALSignature("Pack", UseSmallSig); writer.AddOffset("SectionSize"); writer.Write(FileEntries.Count); // Writes file data entries for (int i = 0; i < FileEntries.Count; ++i) { // Allocates 4 bytes for the absolute address of the contents of the file writer.AddOffset($"DataPtr{i}"); // Writes the length of the file writer.Write(FileEntries[i].Data.Length); } // Fills in the size of the Pack section writer.FillInOffset("SectionSize", (uint)(writer.BaseStream.Position - (UseSmallSig ? 0xC : 0x18))); // Realigns the writer writer.FixPadding(UseSmallSig ? 0x04u : 0x08u); // Data for (int i = 0; i < FileEntries.Count; ++i) { writer.FillInOffset($"DataPtr{i}"); writer.Write(FileEntries[i].Data); // Realigns the writer writer.FixPadding(UseSmallSig ? 0x04u : 0x08u); } // Finalise ZLIB Compression if (Compress) { writer.EndDeflateEncapsulation(mainStream); } }