Esempio n. 1
0
        public override void Load(ExtendedBinaryReader reader, bool keepOpen = false)
        {
            // Store the current reader
            _internalReader = reader;

            // Filename Section
            //  This section contains an array of addresses to each of the file's name and the strings
            //   itself right after, this section is only used for finding file indices from within game

            //  This is a workaround for reading different versions of PCK files as some files seem to
            //   have smaller padding (0x08 for Signatures, 0x04 for Padding)
            //   while DAL: RR has larger padding (0x14 for Signatures, 0x08 for Padding)
            //  This workaround works by checking the padding in the signature to determine the version
            int  sigSize = reader.CheckDALSignature("Filename");
            bool oldPCK  = false;

            if (sigSize < 0x14)
            {
                oldPCK = true;
            }

            // The length of the Filename section
            int fileNameSectionSize = reader.ReadInt32();
            // Address to the list of filenames
            int fileNameSectionAddress = (int)reader.BaseStream.Position;

            // Jump to the Pack section
            reader.JumpTo(fileNameSectionSize);

            // Makes sure the reader is aligned
            reader.FixPadding(oldPCK ? 0x04u : 0x08u);

            // Pack Section
            //  This section contains an array of file information and then all of it's data

            // Check Signature
            string packSig = reader.ReadDALSignature("Pack");

            if (packSig != "Pack" && packSig.Length <= 4)
            {
                throw new SignatureMismatchException("Pack", packSig);
            }

            // The length of the Pack section
            int packSectionSize = reader.ReadInt32();
            int fileCount       = reader.ReadInt32();

            // Read file entries
            for (int i = 0; i < fileCount; ++i)
            {
                FileEntries.Add(new FileEntry());
                FileEntries[i].DataPosition = reader.ReadInt32();
                FileEntries[i].DataLength   = reader.ReadInt32();
            }

            // Jump back to the Filename section so we can get all of the file names
            reader.JumpTo(fileNameSectionAddress);

            // Reads all the file names
            for (int i = 0; i < fileCount; ++i)
            {
                int position = reader.ReadInt32() + (oldPCK ? 0xC : 0x18);
                FileEntries[i].FileName = reader.ReadStringElsewhere(position);
            }

            // Load all data into memory if the loader plans to close the stream
            if (!keepOpen)
            {
                Preload();
            }
        }