From 1357627e2dcd982b17593b1388b53d8ff806a574 Mon Sep 17 00:00:00 2001 From: KillzXGaming Date: Mon, 5 Aug 2019 16:47:40 -0400 Subject: [PATCH] Add pak saving --- .vs/Toolbox/v15/.suo | Bin 914944 -> 914944 bytes .../FileFormats/CrashBandicoot/IGA_PAK.cs | 104 ++++++++++++++++-- .../File_Format_Library.csproj | 5 +- 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/.vs/Toolbox/v15/.suo b/.vs/Toolbox/v15/.suo index 10944068815919329f364b54a696bfd20d1f7ee6..239c4fb331d0a6239441c408afbe7f7ac5ab6d9f 100644 GIT binary patch delta 4198 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 delta 4512 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 diff --git a/File_Format_Library/FileFormats/CrashBandicoot/IGA_PAK.cs b/File_Format_Library/FileFormats/CrashBandicoot/IGA_PAK.cs index ac3986d6..9e9c91dd 100644 --- a/File_Format_Library/FileFormats/CrashBandicoot/IGA_PAK.cs +++ b/File_Format_Library/FileFormats/CrashBandicoot/IGA_PAK.cs @@ -49,24 +49,32 @@ namespace FirstPlugin public void ClearFiles() { files.Clear(); } + public uint Version; + public uint Unknown2; + public uint Alignment; + public uint[] Unknowns3; + public uint[] Hashes; + public void Load(System.IO.Stream stream) { using (var reader = new FileReader(stream)) { + CanSave = true; + reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian; uint Singnature = reader.ReadUInt32(); //IGAx01 - uint Version = reader.ReadUInt32(); //13 + Version = reader.ReadUInt32(); //13 uint FileSectionSize = reader.ReadUInt32(); //Total size of file entires that point to file data uint FileCount = reader.ReadUInt32(); - uint ChunkSize = reader.ReadUInt32(); + Alignment = reader.ReadUInt32(); //Skip some unknowns for now - reader.Seek(20, System.IO.SeekOrigin.Current); + Unknowns3 = reader.ReadUInt32s(5); uint NameTableOffset = reader.ReadUInt32(); uint Padding = reader.ReadUInt32(); uint NameTableSize = reader.ReadUInt32(); - uint Unknown2 = reader.ReadUInt32(); //Always 1? - uint[] Hashes = reader.ReadUInt32s((int)FileCount); + Unknown2 = reader.ReadUInt32(); //Always 1? + Hashes = reader.ReadUInt32s((int)FileCount); //Read the filenames first long pos = reader.Position; @@ -91,7 +99,9 @@ namespace FirstPlugin file.Read(reader); files.Add(file); - // if (Utils.GetExtension(file.FileName) == ".igz") + file.FullName = FileNames[i]; + + // if (Utils.GetExtension(file.FileName) == ".igz") // file.OpenFileFormatOnLoad = true; //Remove this stupid long pointless path @@ -109,6 +119,82 @@ namespace FirstPlugin } } + public void Write(FileWriter writer) + { + writer.WriteSignature("IGA\x01"); + writer.Write(Version); + //total size of file info and hash section + //16 size of info, 4 for size of hash + writer.Write(files.Count * 20); + writer.Write(files.Count); + writer.Write(Alignment); + writer.Write(Unknowns3); + + long _ofsNameTbl = writer.Position; + writer.Write(uint.MaxValue); //NameTableOffset + writer.Write(0); + writer.Write(202518); + writer.Write(1); + writer.Write(Hashes); + + //Now after are file entries + long fileInfoTbl = writer.Position; + for (int i = 0; i < files.Count; i++) + { + writer.Write(uint.MaxValue); //FileOffset + writer.Write(uint.MaxValue); //NameOffset + writer.Write(files[i].DecompressedFileSize); + writer.Write(files[i].FileCompressionType); + } + + writer.Align(128); + + //Now save the file data + for (int i = 0; i < files.Count; i++) + { + long dataPos = writer.Position; + using (writer.TemporarySeek(fileInfoTbl + (i * 16), SeekOrigin.Begin)) { + writer.Write((uint)dataPos); + } + + writer.Write(files[i].FileData); + writer.Align(2048); + } + + //Then write placeholder name offsets + long nameOffsetTbl = writer.Position; + + writer.WriteUint32Offset(_ofsNameTbl); + for (int i = 0; i < files.Count; i++) + { + //Save the file entry name offset + long strOfsPos = writer.Position; + using (writer.TemporarySeek(fileInfoTbl + (i * 16) + 4, SeekOrigin.Begin)) { + writer.Write((uint)(strOfsPos - nameOffsetTbl)); + } + + writer.Write(uint.MaxValue); + } + + long nameTablePos = writer.Position; + + //Now write each string and name offset + for (int i = 0; i < files.Count; i++) + { + long strPos = writer.Position; + using (writer.TemporarySeek(nameOffsetTbl + (i * sizeof(uint)), SeekOrigin.Begin)) { + writer.Write((uint)(strPos - nameOffsetTbl)); + } + + writer.WriteString(files[i].FullName); + } + } + + private void WriteString(FileWriter writer, string name) + { + + } + public void Unload() { @@ -116,7 +202,9 @@ namespace FirstPlugin public byte[] Save() { - return null; + var mem = new System.IO.MemoryStream(); + Write(new FileWriter(mem)); + return mem.ToArray(); } public bool AddFile(ArchiveFileInfo archiveFileInfo) @@ -131,6 +219,8 @@ namespace FirstPlugin public class FileEntry : ArchiveFileInfo { + public string FullName { get; set; } + //The archive file used to open the file public string SourceFile { get; set; } diff --git a/File_Format_Library/File_Format_Library.csproj b/File_Format_Library/File_Format_Library.csproj index 94617666..bce02cfa 100644 --- a/File_Format_Library/File_Format_Library.csproj +++ b/File_Format_Library/File_Format_Library.csproj @@ -206,6 +206,7 @@ + @@ -275,8 +276,8 @@ - - + +