Ejemplo n.º 1
0
        /// <summary>
        ///     Reads a generic Pokémon container from a Stream.
        ///     Those containers are the ones that starts with "GR", "MM", "AD" and so on...
        /// </summary>
        /// <param name="data">Stream with container data</param>
        /// <returns></returns>
        public static OContainer load(Stream data)
        {
            BinaryReader input  = new BinaryReader(data);
            OContainer   output = new OContainer();

            IOUtils.readString(input, 0, 2); //Magic
            ushort sectionCount = input.ReadUInt16();

            for (int i = 0; i < sectionCount; i++)
            {
                OContainer.fileEntry entry = new OContainer.fileEntry();

                data.Seek(4 + (i * 4), SeekOrigin.Begin);
                uint startOffset = input.ReadUInt32();
                uint endOffset   = input.ReadUInt32();
                uint length      = endOffset - startOffset;

                data.Seek(startOffset, SeekOrigin.Begin);
                byte[] buffer = new byte[length];
                input.Read(buffer, 0, (int)length);
                entry.data = buffer;

                output.content.Add(entry);
            }

            data.Close();

            return(output);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Reads a GARC archive.
        /// </summary>
        /// <param name="data">Stream of the data</param>
        /// <returns>The container data</returns>
        public static OContainer load(Stream data)
        {
            OContainer   output = new OContainer();
            BinaryReader input  = new BinaryReader(data);

            output.data = data;

            string garcMagic        = IOUtils.readStringWithLength(input, 4);
            uint   garcHeaderLength = input.ReadUInt32();
            ushort endian           = input.ReadUInt16();

            input.ReadUInt16(); //0x400
            uint sectionCount       = input.ReadUInt32();
            uint dataOffset         = input.ReadUInt32();
            uint decompressedLength = input.ReadUInt32();
            uint compressedLength   = input.ReadUInt32();

            //File Allocation Table Offsets
            string fatoMagic        = IOUtils.readStringWithLength(input, 4);
            uint   fatoHeaderLength = input.ReadUInt32();
            ushort fatoEntries      = input.ReadUInt16();

            input.ReadUInt16();                             //0xffff = Padding?
            data.Seek(fatoEntries * 4, SeekOrigin.Current); //We don't need this

            string fatbMagic        = IOUtils.readStringWithLength(input, 4);
            uint   fatbHeaderLength = input.ReadUInt32();
            uint   entries          = input.ReadUInt32();

            long baseOffset = data.Position;

            for (int i = 0; i < entries; i++)
            {
                data.Seek(baseOffset + i * 0x10, SeekOrigin.Begin);

                uint flags       = input.ReadUInt32();
                uint startOffset = input.ReadUInt32();
                uint endOffset   = input.ReadUInt32();
                uint length      = input.ReadUInt32();

                input.BaseStream.Seek(startOffset + dataOffset, SeekOrigin.Begin);
                byte[] buffer = new byte[Math.Min(0x10, length)];
                input.Read(buffer, 0, buffer.Length);

                bool   isCompressed = buffer.Length > 0 ? buffer[0] == 0x11 : false;
                string extension    = FileIO.getExtension(buffer, isCompressed ? 5 : 0);
                string name         = string.Format("file_{0:D5}{1}", i, extension);

                //And add the file to the container list
                OContainer.fileEntry entry = new OContainer.fileEntry();
                entry.name         = name;
                entry.loadFromDisk = true;
                entry.fileOffset   = startOffset + dataOffset;
                entry.fileLength   = length;
                output.content.Add(entry);
            }

            return(output);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Reads a SARC archive.
        /// </summary>
        /// <param name="data">Stream of the data</param>
        /// <returns>The container data</returns>
        public static OContainer load(Stream data)
        {
            OContainer   output = new OContainer();
            BinaryReader input  = new BinaryReader(data);

            string sarcMagic        = IOUtils.readStringWithLength(input, 4);
            ushort sarcHeaderLength = input.ReadUInt16();
            ushort endian           = input.ReadUInt16();
            uint   fileLength       = input.ReadUInt32();
            uint   dataOffset       = input.ReadUInt32();
            uint   dataPadding      = input.ReadUInt32();

            string sfatMagic        = IOUtils.readStringWithLength(input, 4);
            ushort sfatHeaderLength = input.ReadUInt16();
            ushort entries          = input.ReadUInt16();
            uint   hashMultiplier   = input.ReadUInt32();
            int    sfntOffset       = 0x20 + entries * 0x10 + 8;

            for (int i = 0; i < entries; i++)
            {
                data.Seek(0x20 + i * 0x10, SeekOrigin.Begin);

                uint nameHash   = input.ReadUInt32();
                uint nameOffset = (input.ReadUInt32() & 0xffffff) << 2;
                uint offset     = input.ReadUInt32();
                uint length     = input.ReadUInt32() - offset;

                string name = IOUtils.readString(input, (uint)(sfntOffset + nameOffset));
                data.Seek(offset + dataOffset, SeekOrigin.Begin);
                byte[] buffer = new byte[length];
                data.Read(buffer, 0, buffer.Length);
                if (name == "")
                {
                    name = string.Format("file_{0:D5}{1}", i, FileIO.getExtension(buffer));
                }

                OContainer.fileEntry entry = new OContainer.fileEntry();
                entry.name = name;
                entry.data = buffer;
                output.content.Add(entry);
            }

            data.Close();
            return(output);
        }
Ejemplo n.º 4
0
        /// <summary>
        ///     Reads FPT0 containers from Dragon Quest VII.
        /// </summary>
        /// <param name="data">Stream with container data</param>
        /// <returns></returns>
        public static OContainer load(Stream data)
        {
            BinaryReader input  = new BinaryReader(data);
            OContainer   output = new OContainer();

            data.Seek(8, SeekOrigin.Begin);
            uint entries     = input.ReadUInt32();
            uint baseAddress = 0x10 + (entries * 0x20) + 0x80;

            input.ReadUInt32();

            List <sectionEntry> files = new List <sectionEntry>();

            for (int i = 0; i < entries; i++)
            {
                sectionEntry entry = new sectionEntry();

                entry.name = IOUtils.readString(input, (uint)(0x10 + (i * 0x20)));
                data.Seek(0x20 + (i * 0x20), SeekOrigin.Begin);
                input.ReadUInt32(); //Memory address?
                entry.offset = input.ReadUInt32() + baseAddress;
                entry.length = input.ReadUInt32();
                input.ReadUInt32(); //Padding?

                files.Add(entry);
            }

            foreach (sectionEntry file in files)
            {
                OContainer.fileEntry entry = new OContainer.fileEntry();

                data.Seek(file.offset, SeekOrigin.Begin);
                byte[] buffer = new byte[file.length];
                input.Read(buffer, 0, buffer.Length);
                entry.data = buffer;
                entry.name = file.name;

                output.content.Add(entry);
            }

            data.Close();

            return(output);
        }
Ejemplo n.º 5
0
        /// <summary>
        ///     Reads the Model PACKage from Dragon Quest VII.
        /// </summary>
        /// <param name="data">Stream of the data</param>
        /// <returns></returns>
        public static OContainer load(Stream data)
        {
            BinaryReader input  = new BinaryReader(data);
            OContainer   output = new OContainer();

            List <sectionEntry> mainSection = getSection(input);

            //World nodes section
            data.Seek(mainSection[0].offset, SeekOrigin.Begin);
            List <node>         nodes             = new List <node>();
            List <sectionEntry> worldNodesSection = getSection(input);

            foreach (sectionEntry entry in worldNodesSection)
            {
                data.Seek(entry.offset, SeekOrigin.Begin);

                node n = new node();

                //Geometry node
                input.ReadUInt32(); //GNOD magic number
                input.ReadUInt32();
                input.ReadUInt32();
                n.parentId = input.ReadInt32();
                n.name     = IOUtils.readString(input, (uint)data.Position);

                data.Seek(entry.offset + 0x20, SeekOrigin.Begin);
                n.transform = new RenderBase.OMatrix();
                RenderBase.OVector4 t = new RenderBase.OVector4(input.ReadSingle(), input.ReadSingle(), input.ReadSingle(), input.ReadSingle());
                RenderBase.OVector4 r = new RenderBase.OVector4(input.ReadSingle(), input.ReadSingle(), input.ReadSingle(), input.ReadSingle());
                RenderBase.OVector4 s = new RenderBase.OVector4(input.ReadSingle(), input.ReadSingle(), input.ReadSingle(), input.ReadSingle());
                n.transform *= RenderBase.OMatrix.scale(new RenderBase.OVector3(s.x, s.y, s.z));
                n.transform *= RenderBase.OMatrix.rotateX(r.x);
                n.transform *= RenderBase.OMatrix.rotateY(r.y);
                n.transform *= RenderBase.OMatrix.rotateZ(r.z);
                n.transform *= RenderBase.OMatrix.translate(new RenderBase.OVector3(t.x, t.y, t.z));

                nodes.Add(n);
            }

            RenderBase.OMatrix[] nodesTransform = new RenderBase.OMatrix[nodes.Count];
            for (int i = 0; i < nodes.Count; i++)
            {
                RenderBase.OMatrix transform = new RenderBase.OMatrix();
                transformNode(nodes, i, ref transform);
                nodesTransform[i] = transform;
            }

            //Models section
            data.Seek(mainSection[1].offset, SeekOrigin.Begin);
            List <sectionEntry> modelsSection = getSection(input);

            foreach (sectionEntry entry in modelsSection)
            {
                data.Seek(entry.offset, SeekOrigin.Begin);

                //Field Data section

                /*
                 * Usually have 3 entries.
                 * 1st entry: Model CGFX
                 * 2nd entry: Unknow CGFX, possibly animations
                 * 3rd entry: Another FieldData section, possibly child object
                 */

                List <sectionEntry> fieldDataSection = getSection(input);
                data.Seek(fieldDataSection[0].offset, SeekOrigin.Begin);
                uint length = fieldDataSection[0].length;
                while ((length & 0x7f) != 0)
                {
                    length++;                          //Align
                }
                byte[] buffer = new byte[length];
                input.Read(buffer, 0, buffer.Length);

                OContainer.fileEntry file = new OContainer.fileEntry();
                file.name = CGFX.getName(new MemoryStream(buffer)) + ".bcmdl";
                file.data = buffer;

                output.content.Add(file);
            }

            //FILE section
            data.Seek(mainSection[2].offset, SeekOrigin.Begin);
            //TODO

            //Collision section
            data.Seek(mainSection[3].offset, SeekOrigin.Begin);
            //TODO

            //PARM(???) section
            data.Seek(mainSection[4].offset, SeekOrigin.Begin);
            //TODO

            //Textures CGFX
            data.Seek(mainSection[5].offset, SeekOrigin.Begin);
            byte[] texBuffer = new byte[mainSection[5].length];
            input.Read(texBuffer, 0, texBuffer.Length);

            OContainer.fileEntry texFile = new OContainer.fileEntry();
            texFile.name = "textures.bctex";
            texFile.data = texBuffer;

            output.content.Add(texFile);

            data.Close();

            return(output);
        }
Ejemplo n.º 6
0
        /// <summary>
        ///     Reads a DARC archive.
        /// </summary>
        /// <param name="data">Stream of the data</param>
        /// <returns>The container data</returns>
        public static OContainer load(Stream data)
        {
            OContainer   output = new OContainer();
            BinaryReader input  = new BinaryReader(data);

            string darcMagic    = IOUtils.readStringWithLength(input, 4);
            ushort endian       = input.ReadUInt16();
            ushort headerLength = input.ReadUInt16();
            uint   version      = input.ReadUInt32();
            uint   fileSize     = input.ReadUInt32();
            uint   tableOffset  = input.ReadUInt32();
            uint   tableLength  = input.ReadUInt32();
            uint   dataOffset   = input.ReadUInt32();

            data.Seek(tableOffset, SeekOrigin.Begin);
            fileEntry root        = getEntry(input);
            int       baseOffset  = (int)data.Position;
            int       namesOffset = (int)(tableOffset + root.length * 0xc);

            string currDir = null;

            for (int i = 0; i < root.length - 1; i++)
            {
                data.Seek(baseOffset + i * 0xc, SeekOrigin.Begin);

                fileEntry entry = getEntry(input);

                if ((entry.flags & 1) > 0)
                {
                    //Folder
                    int index = i;
                    currDir = null;
                    for (;;)
                    {
                        uint parentIndex = entry.offset;
                        currDir = getName(input, entry.nameOffset + namesOffset) + "/" + currDir;
                        if (parentIndex == 0 || parentIndex == index)
                        {
                            break;
                        }
                        data.Seek(baseOffset + parentIndex * 0xc, SeekOrigin.Begin);
                        entry = getEntry(input);
                        index = (int)parentIndex;
                    }

                    continue;
                }

                data.Seek(entry.offset, SeekOrigin.Begin);
                byte[] buffer = new byte[entry.length];
                data.Read(buffer, 0, buffer.Length);

                OContainer.fileEntry file = new OContainer.fileEntry();
                file.name = currDir + getName(input, entry.nameOffset + namesOffset);
                file.data = buffer;

                output.content.Add(file);
            }

            data.Close();
            return(output);
        }