예제 #1
0
        public override void Load(ExtendedBinaryReader reader, bool keepOpen = false)
        {
            string header = reader.ReadNullTerminatedString();

            reader.FixPadding(16);
            uint   textureOffset = reader.ReadUInt32();
            uint   textureCount  = reader.ReadUInt32();
            int    layerOffset   = reader.ReadInt32();
            int    layerCount    = reader.ReadInt32();
            int    unknownOffset = reader.ReadInt32();
            int    unknownCount  = reader.ReadInt32();
            uint   unknown28     = reader.ReadUInt32();
            uint   unknown2C     = reader.ReadUInt32();
            string projectDir    = reader.ReadStringElsewhere();
            uint   unknown34     = reader.ReadUInt32();
            uint   unknown38     = reader.ReadUInt32();
            uint   unknown3C     = reader.ReadUInt32();

            reader.JumpTo(textureOffset);
            for (int i = 0; i < textureCount; ++i)
            {
                Textures.Add(new MATexture(reader));
            }

            reader.JumpTo(layerOffset);
            for (int i = 0; i < layerCount; ++i)
            {
                Layers.Add(new MALayer(reader));
            }
        }
예제 #2
0
        // TODO
        protected void LoadShadowArchive(ExtendedBinaryReader reader)
        {
            reader.JumpAhead(0x4);                                 // Unknown, Seems to always be 0
            uint   fileSize   = reader.ReadUInt32();               // File Size - 0xC
            uint   magic      = reader.ReadUInt32();               // Magic
            string ONEVersion = reader.ReadNullTerminatedString(); // Gets the version String

            reader.FixPadding();                                   // Aligns the reader

            uint fileCount = reader.ReadUInt32();                  // File Count

            reader.JumpAhead(0x38 * 2 + 0x20);                     // Jump to the third/first entry
            bool isVersion6     = ONEVersion == "ONE Ver 0.60";    // Checks if its version is 0.60
            int  fileNameLength = isVersion6 ? 0x2C : 0x20;        // The max file name size

            // Read File List
            var files = new FileEntry[FileEntryCount];

            for (int i = 0; i < fileCount; i++)
            {
                var entry = new FileEntry();
                entry.FileName = reader.ReadSignature(
                    fileNameLength).Replace("\0", string.Empty);

                entry.UncompressedSize = reader.ReadUInt32();
                entry.DataOffset       = reader.ReadUInt32();
                reader.JumpAhead(4); // Unknown, Seems to always be 1

                if (!isVersion6)
                {
                    reader.JumpAhead(0xC); // Unknown, Seems to always be 0
                }
                files[i] = entry;
            }

            // Read File Data
            if (files.Length > 0)
            {
                reader.JumpTo(files[0].DataOffset + 0xC);
                for (int i = 0; i < fileCount; ++i)
                {
                    // Compute the file's data length
                    files[i].DataLength = ((i == fileCount - 1) ?
                                           fileSize + 0xC : files[i + 1].DataOffset) - files[i].DataOffset;

                    var file = new ArchiveFile()
                    {
                        Name = files[i].FileName,
                        Data = reader.ReadBytes(
                            (int)files[i].DataLength) // TODO: Decompress file
                    };
                    Data.Add(file);
                }
            }
        }
        protected void FixPadding(ExtendedBinaryReader reader, Type t)
        {
            uint padding = GetPadding(t);

            if (padding < 2)
            {
                return;
            }

            reader.FixPadding(padding);
        }
예제 #4
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();
            }
        }
예제 #5
0
        private static SetObject ReadObject(ExtendedBinaryReader reader,
                                            SetObjectType objTemplate, string objType, SOBJType type,
                                            bool rawDataMode = false) // true = full, false = only remaining bytes
        {
            // For some reason these separate values are saved as one uint rather than two ushorts.
            // Because of this, the values are in a different order depending on endianness, and
            // this is the easiest known way to read them.
            uint   unknownValue = reader.ReadUInt32();
            ushort unknown1     = (ushort)((unknownValue >> 16) & 0xFFFF);
            ushort objID        = (ushort)(unknownValue & 0xFFFF);

            var obj = new SetObject()
            {
                ObjectType = objType,
                ObjectID   = objID
            };

            uint  unknown2 = reader.ReadUInt32();
            uint  unknown3 = reader.ReadUInt32();
            float unknown4 = reader.ReadSingle();

            float rangeIn          = reader.ReadSingle();
            float rangeOut         = reader.ReadSingle();
            uint  parent           = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;
            uint  transformsOffset = reader.ReadUInt32();

            uint transformCount = reader.ReadUInt32();
            uint unknown5       = reader.ReadUInt32();
            uint unknown6       = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;
            uint unknown7       = (type == SOBJType.LostWorld) ? reader.ReadUInt32() : 0;

            // Call me crazy, but I have a weird feeling these values aren't JUST padding
            if (unknown3 != 0 || unknown5 != 0 || unknown6 != 0 || unknown7 != 0)
            {
                Console.WriteLine("WARNING: Not padding?! ({0},{1},{2},{3})",
                                  unknown3, unknown5, unknown6, unknown7);
            }

            // Add custom data to object
            obj.CustomData.Add("Unknown1", new SetObjectParam(typeof(ushort), unknown1));
            obj.CustomData.Add("Unknown2", new SetObjectParam(typeof(uint), unknown2));
            obj.CustomData.Add("Unknown3", new SetObjectParam(typeof(uint), unknown3));
            obj.CustomData.Add("Unknown4", new SetObjectParam(typeof(float), unknown4));
            obj.CustomData.Add("RangeIn", new SetObjectParam(typeof(float), rangeIn));
            obj.CustomData.Add("RangeOut", new SetObjectParam(typeof(float), rangeOut));

            if (type == SOBJType.LostWorld)
            {
                obj.CustomData.Add("Parent", new SetObjectParam(typeof(uint), parent));
            }

            // Skip loading parameters if template doesn't exist
            if (objTemplate != null)
            {
                // Get Raw Byte Length
                var  rawDataLenExtra = objTemplate.GetExtra("RawByteLength");
                long paramBegin      = reader.BaseStream.Position;
                int  rawLength       = 0;

                if (rawDataLenExtra != null &&
                    !string.IsNullOrEmpty(rawDataLenExtra.Value))
                {
                    int.TryParse(rawDataLenExtra.Value, out rawLength);
                }

                // Read all the data then return to beginning
                if (rawDataMode == true && rawLength != 0)
                {
                    obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]),
                                                                          reader.ReadBytes(rawLength)));
                    reader.JumpTo(paramBegin);
                }

                // Parameters
                foreach (var param in objTemplate.Parameters)
                {
                    // For compatibility with SonicGlvl templates.
                    if (param.Name == "Unknown1" || param.Name == "Unknown2" ||
                        param.Name == "Unknown3" || param.Name == "RangeIn" ||
                        param.Name == "RangeOut" || param.Name == "Parent")
                    {
                        continue;
                    }

                    // Read Special Types/Fix Padding
                    if (param.DataType == typeof(uint[]))
                    {
                        // Data Info
                        reader.FixPadding(4);
                        uint arrOffset  = reader.ReadUInt32();
                        uint arrLength  = reader.ReadUInt32();
                        uint arrUnknown = reader.ReadUInt32();
                        long curPos     = reader.BaseStream.Position;

                        // Data
                        var arr = new uint[arrLength];
                        reader.JumpTo(arrOffset, false);

                        for (uint i = 0; i < arrLength; ++i)
                        {
                            arr[i] = reader.ReadUInt32();
                        }

                        obj.Parameters.Add(new SetObjectParam(param.DataType, arr));
                        reader.BaseStream.Position = curPos;
                        continue;
                    }
                    else if (param.DataType == typeof(string))
                    {
                        // Data Info
                        uint   strOffset  = reader.ReadUInt32();
                        uint   strUnknown = reader.ReadUInt32();
                        string str        = null;

                        // Data
                        if (strOffset != 0)
                        {
                            long curPos = reader.BaseStream.Position;
                            reader.JumpTo(strOffset, false);

                            str = reader.ReadNullTerminatedString();
                            reader.BaseStream.Position = curPos;
                        }

                        obj.Parameters.Add(new SetObjectParam(param.DataType, str));
                        continue;
                    }
                    else if (param.DataType == typeof(float) ||
                             param.DataType == typeof(int) || param.DataType == typeof(uint))
                    {
                        reader.FixPadding(4);
                    }
                    else if (type == SOBJType.LostWorld && param.DataType == typeof(Vector3))
                    {
                        reader.FixPadding(16);
                    }

                    // Read Data
                    var objParam = new SetObjectParam(param.DataType,
                                                      reader.ReadByType(param.DataType));
                    obj.Parameters.Add(objParam);
                }

                if (rawDataMode == false)
                {
                    long knownParamLength = (reader.BaseStream.Position - paramBegin);
                    long remainingBytes   = (rawLength - knownParamLength);

                    obj.CustomData.Add("RawParamData", new SetObjectParam(typeof(byte[]),
                                                                          reader.ReadBytes((int)remainingBytes)));
                }
            }

            // Transforms
            uint childCount = transformCount - 1;

            obj.Children = new SetObjectTransform[childCount];
            reader.JumpTo(transformsOffset, false);

            obj.Transform = ReadTransform(reader, type == SOBJType.LostWorld);
            for (uint i = 0; i < childCount; ++i)
            {
                obj.Children[i] = ReadTransform(reader,
                                                type == SOBJType.LostWorld);
            }

            return(obj);
        }