private void SetupSTRM(Game game, Platform platform) { // Let's generate a temporary HIP file that will be discarded. This sets a correct STRM.DPAK.globalRelativeStartOffset List <byte> temporaryFile = new List <byte>(); HIPA.SetBytes(game, platform, ref temporaryFile); PACK.PCNT = new Section_PCNT(0, 0, 0, 0, 0); PACK.SetBytes(game, platform, ref temporaryFile); DICT.SetBytes(game, platform, ref temporaryFile); STRM.DPAK = new Section_DPAK() { data = new byte[0] }; STRM.SetBytes(game, platform, ref temporaryFile); // Create the new STRM stream. List <byte> newStream = new List <byte>(); // Sort the ATOC data (AHDR sections) by their asset ID. Unsure if this is necessary, but just in case. // DICT.ATOC.AHDRList = DICT.ATOC.AHDRList.OrderBy(AHDR => AHDR.GetCompareValue(platform)).ToList(); // Let's build a temporary dictionary with the assets, so we can write them in layer order. Dictionary <uint, Section_AHDR> assetDictionary = new Dictionary <uint, Section_AHDR>(); foreach (Section_AHDR AHDR in DICT.ATOC.AHDRList) { assetDictionary.Add(AHDR.assetID, AHDR); } // Let's go through each layer. foreach (Section_LHDR LHDR in DICT.LTOC.LHDRList) { // Sort the LDBG asset IDs. The AHDR data will then be written in this order. LHDR.assetIDlist = LHDR.assetIDlist.OrderBy(i => DICT.ATOC.GetFromAssetID(i).GetCompareValue(game, platform)).ToList(); int finalAlignment = platform == Platform.GameCube ? 0x20 : 0x800; for (int i = 0; i < LHDR.assetIDlist.Count; i++) { if (!assetDictionary.ContainsKey(LHDR.assetIDlist[i])) { LHDR.assetIDlist.RemoveAt(i); i--; continue; } Section_AHDR AHDR = assetDictionary[LHDR.assetIDlist[i]]; // Set stream dependant AHDR data... AHDR.fileOffset = newStream.Count + STRM.DPAK.globalRelativeStartOffset; AHDR.fileSize = AHDR.data.Length; // And add the data to the stream. newStream.AddRange(AHDR.data); // Calculate alignment data which I don't understand, but hey it works. AHDR.plusValue = 0; int alignment = 16; if (game == Game.BFBB && AHDR.assetType == AssetType.CSN || AHDR.assetType == AssetType.SND || AHDR.assetType == AssetType.SNDS) { alignment = finalAlignment; AHDR.ADBG.alignment = alignment; } else { AHDR.ADBG.alignment = 0; } int value = AHDR.fileSize % alignment; if (value != 0) { AHDR.plusValue = alignment - value; } for (int j = 0; j < AHDR.plusValue; j++) { newStream.Add(0x33); } } while ((newStream.Count + STRM.DPAK.globalRelativeStartOffset) % finalAlignment != 0) { newStream.Add(0x33); } } // Assign list as stream! We're done with the worst part. STRM.DPAK.data = newStream.ToArray(); // I'll create a new PCNT, because I'm sure you'll forget to do so. PACK.PCNT = new Section_PCNT(DICT.ATOC.AHDRList.Count, DICT.LTOC.LHDRList.Count); }