/// <summary> /// Recalculate the BND4 headers from entry data. /// </summary> public void CalculateHeaders() { if (DEBUG) { Console.WriteLine("[DEBUG] RECALCULATE HEADERS"); } // 1st pass, do names uint cDataOffset = (uint)(Marshal.SizeOf <BND4Header>() + entries.Length * Marshal.SizeOf <BND4EntryHeader>()); foreach (BND4Entry entry in entries) { entry.header = new BND4EntryHeader((ulong)entry.data.Length, 0, cDataOffset); cDataOffset += (isUnicode ? 2U : 1U) * (uint)(entry.name.Length + 1); } // Pad cDataOffset to a multiple of 16 bytes cDataOffset += (16U - cDataOffset % 16U) % 16U; // Fix main header header = new BND4Header((uint)entries.Length, cDataOffset, isUnicode); // 2nd pass, do file offsets foreach (BND4Entry entry in entries) { entry.header.entryDataOffset = cDataOffset; cDataOffset += (uint)entry.header.entrySize; // Pad to a multiple of 16 bytes cDataOffset += (16U - cDataOffset % 16U) % 16U; } }
/// <summary> /// Load a BND4 file into the existing object, overwriting existing data. /// </summary> /// <param name="filePath"></param> public void LoadInPlace(string filePath) { Utils.Assert(File.Exists(filePath), "File does not exist"); using (BinReader bin = new BinReader(File.OpenRead(filePath))) { if (DEBUG) { Console.WriteLine("[DEBUG] READ BND4 HEADERS"); } header = bin.ReadStruct <BND4Header>(); header.AssertIntegrity(); isUnicode = header.isUnicode; entries = new BND4Entry[header.fileCnt]; for (int i = 0; i < header.fileCnt; i++) { if (DEBUG) { Console.WriteLine(string.Format("[DEBUG] READ ENTRY HEADER {0}/{1}", i + 1, header.fileCnt)); } entries[i] = new BND4Entry(); entries[i].header = bin.ReadStruct <BND4EntryHeader>(); entries[i].header.AssertIntegrity(); if (DEBUG) { Console.WriteLine(string.Format("[DEBUG] READ ENTRY NAME {0}/{1}", i + 1, header.fileCnt)); } bin.StepInto(entries[i].header.entryNameOffset); entries[i].name = header.isUnicode ? bin.ReadWideString() : bin.ReadShiftJIS(); bin.StepOut(); if (DEBUG) { Console.WriteLine(string.Format("[DEBUG] READ ENTRY DATA {0}/{1}", i + 1, header.fileCnt)); } bin.StepInto(entries[i].header.entryDataOffset); entries[i].data = bin.ReadBytes((int)entries[i].header.entrySize); bin.StepOut(); } if (DEBUG) { Console.WriteLine("[DEBUG] READ COMPLETE"); } } }