Пример #1
0
        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);
        }