private bool LoadFile(byte[] File) { uint PointerCount = Util.ToUInt24(File, 0); List <uint> Pointers = new List <uint>((int)PointerCount); for (int i = 0; i < PointerCount; ++i) { Pointers.Add(Util.ToUInt24(File, 0x03 + i * 0x03)); } // create sections we fill in later, so we can remember the original order Sections = new List <scrSection>(); // one dummy at the start for anything before the first pointer scrSection sec = new scrSection(); sec.PointerIndex = -1; sec.Location = 0; Sections.Add(sec); for (int i = 0; i < Pointers.Count; ++i) { sec = new scrSection(); sec.PointerIndex = i; sec.Location = Pointers[i]; Sections.Add(sec); } // sort by Location so we don't read any code/text more than once Sections.Sort(); // one dummy section at end to make the next loop simpler uint HeaderEnd = PointerCount * 0x03 + 0x03; sec = new scrSection(); sec.PointerIndex = Pointers.Count; sec.Location = (uint)File.Length - HeaderEnd; Sections.Add(sec); // read the file into code and strings for (int i = 0; i < Sections.Count - 1; ++i) { uint Pointer = Sections[i].Location + HeaderEnd; uint EndPointer = Sections[i + 1].Location + HeaderEnd; List <scrElement> l = scrElement.LoadAt(File, Pointer, EndPointer); Sections[i].Elements = l; } return(true); }
public void CreateFile(string Filename) { // make sure it's sorted by pointer Sections.Sort(); List <byte> b = new List <byte>(); uint OriginalLocation = 0xFFFFFFFF; for (int i = 0; i < Sections.Count; ++i) { scrSection s = Sections[i]; if (s.Elements == null) { continue; } // okay, so we have an issue here: if multiple sections originally pointed to the same thing, // all pointers that come here after the section that has the elements will point to the wrong (next) thing // so we need to compare the original location, and match it if it matched before if (OriginalLocation == s.Location) { s.Location = Sections[i - 1].Location; } else { OriginalLocation = s.Location; s.Location = (uint)b.Count; } foreach (scrElement e in s.Elements) { switch (e.Type) { case HyoutaTools.Narisokonai.scrElement.scrElementType.Code: b.AddRange(e.Code); break; case HyoutaTools.Narisokonai.scrElement.scrElementType.Text: b.AddRange(Util.StringToBytesShiftJis(e.Text)); break; } b.Add(0xFE); b.Add(0xFE); } if (s.Elements.Count > 0) { // remove the last 0xFEFE, it's not in the original files, just makes the code easier to do it this way b.RemoveAt(b.Count - 1); b.RemoveAt(b.Count - 1); } } // sort by pointer index to get the original pointer order back Sections.Sort(new scrSectionPointerIndexComparer()); // create the header List <byte> Header = new List <byte>(); uint ptrCount = 0; foreach (scrSection s in Sections) { if (s.PointerIndex == -1 || s.Elements == null) { continue; } Header.AddRange(Util.GetBytesForUInt24(s.Location)); ++ptrCount; } // and combine all this List <byte> File = new List <byte>(3 + Header.Count + b.Count); File.AddRange(Util.GetBytesForUInt24(ptrCount)); File.AddRange(Header); File.AddRange(b); System.IO.File.WriteAllBytes(Filename, File.ToArray()); }