示例#1
0
        public override void Read(string filename)
        {
            FileData f = new FileData(filename);

            f.Endian = Endianness.Big;
            f.seek(4);
            if (f.readUInt() != Magic)
            {
                return;
            }

            f.seek(0);
            uint bom = f.readUInt();

            if (bom == 0xFFFE0000)
            {
                Endian = Endianness.Little;
            }
            else if (bom == 0x0000FEFF)
            {
                Endian = Endianness.Big;
            }
            else
            {
                return;
            }
            f.Endian = Endian;

            f.seek(8);
            f.readInt(); // Always 0
            int frameCount = f.readInt();

            for (int i = 0; i < frameCount; i++)
            {
                pathFrame temp;
                temp.qx = f.readFloat();
                temp.qy = f.readFloat();
                temp.qz = f.readFloat();
                temp.qw = f.readFloat();
                temp.x  = f.readFloat();
                temp.y  = f.readFloat();
                temp.z  = f.readFloat();
                Frames.Add(temp);
            }
        }
示例#2
0
        public void read(FileData f)
        {
            f.Endian = Endian;
            if (f.size() < 4)
            {
                return;
            }

            f.seek(4);
            unknown    = f.readUInt();
            frameCount = f.readUInt();
            startFrame = f.readUInt();
            endFrame   = f.readUInt();
            frameRate  = f.readUInt();
            int matCount  = f.readInt();
            int matOffset = f.readInt();
            int visCount  = f.readInt();
            int visOffset = f.readInt();
            int returnPos;

            f.seek(matOffset);
            for (int i = 0; i < matCount; i++)
            {
                returnPos = f.pos() + 4;
                f.seek(f.readInt());
                MatEntry tempMatEntry = new MatEntry();
                tempMatEntry.read(f);
                matEntries.Add(tempMatEntry);
                f.seek(returnPos);
            }
            f.seek(visOffset);
            for (int i = 0; i < visCount; i++)
            {
                returnPos = f.pos() + 4;
                f.seek(f.readInt());
                VisEntry tempVisEntry = new VisEntry();
                tempVisEntry.read(f);
                visEntries.Add(tempVisEntry);
                f.seek(returnPos);
            }
        }
示例#3
0
        public void Read(FileData d)
        {
            Endian   = Endianness.Big;
            d.Endian = Endian;
            uint magic = d.readUInt();

            if (magic == 0x4E545033)
            {
                ReadNTP3(d);
            }
            else if (magic == 0x4E545755)
            {
                ReadNTWU(d);
            }
            else if (magic == 0x4E545744)
            {
                d.Endian = Endianness.Little;
                ReadNTP3(d);
            }
        }
示例#4
0
        public void Read(FileData d)
        {
            Endian   = Endianness.Big;
            d.Endian = Endian;

            uint magic = d.readUInt();

            Version = d.readUShort();

            if (magic == 0x4E545033) //NTP3
            {
                ReadNTP3(d);
            }
            else if (magic == 0x4E545755) //NTWU
            {
                ReadNTWU(d);
            }
            else if (magic == 0x4E545744) //NTWD
            {
                Endian   = Endianness.Little;
                d.Endian = Endian;
                ReadNTP3(d);
            }
        }
示例#5
0
        public void ReadNTWU(FileData d)
        {
            d.seek(0x4);

            Version = d.readUShort();
            ushort count = d.readUShort();

            d.skip(0x8);
            int headerPtr = 0x10;

            for (ushort i = 0; i < count; ++i)
            {
                d.seek(headerPtr);

                NutTexture tex = new NutTexture();
                tex.pixelInternalFormat = PixelInternalFormat.Rgba32ui;

                int totalSize = d.readInt();
                d.skip(4);
                int dataSize   = d.readInt();
                int headerSize = d.readUShort();
                d.skip(2);

                d.skip(1);
                byte mipmapCount = d.readByte();
                d.skip(1);
                tex.setPixelFormatFromNutFormat(d.readByte());
                tex.Width  = d.readUShort();
                tex.Height = d.readUShort();
                d.readInt(); //Always 1?
                uint caps2 = d.readUInt();

                bool isCubemap    = false;
                byte surfaceCount = 1;
                if ((caps2 & (uint)DDS.DDSCAPS2.CUBEMAP) == (uint)DDS.DDSCAPS2.CUBEMAP)
                {
                    //Only supporting all six faces
                    if ((caps2 & (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES) == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
                    {
                        isCubemap    = true;
                        surfaceCount = 6;
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported cubemap face amount for texture {i} with hash 0x{tex.HashId:X}. Six faces are required.");
                    }
                }

                int dataOffset      = d.readInt() + headerPtr;
                int mipDataOffset   = d.readInt() + headerPtr;
                int gtxHeaderOffset = d.readInt() + headerPtr;
                d.readInt();

                int cmapSize1 = 0;
                int cmapSize2 = 0;
                if (isCubemap)
                {
                    cmapSize1 = d.readInt();
                    cmapSize2 = d.readInt();
                    d.skip(8);
                }

                int imageSize = 0; //Total size of first mipmap of every surface
                int mipSize   = 0; //Total size of mipmaps other than the first of every surface
                if (mipmapCount == 1)
                {
                    if (isCubemap)
                    {
                        imageSize = cmapSize1;
                    }
                    else
                    {
                        imageSize = dataSize;
                    }
                }
                else
                {
                    imageSize = d.readInt();
                    mipSize   = d.readInt();
                    d.skip((mipmapCount - 2) * 4);
                    d.align(0x10);
                }

                d.skip(0x10); //eXt data - always the same

                d.skip(4);    //GIDX
                d.readInt();  //Always 0x10
                tex.HashId = d.readInt();
                d.skip(4);    // padding align 8

                d.seek(gtxHeaderOffset);
                GTX.GX2Surface gtxHeader = new GTX.GX2Surface();

                gtxHeader.dim       = d.readInt();
                gtxHeader.width     = d.readInt();
                gtxHeader.height    = d.readInt();
                gtxHeader.depth     = d.readInt();
                gtxHeader.numMips   = d.readInt();
                gtxHeader.format    = d.readInt();
                gtxHeader.aa        = d.readInt();
                gtxHeader.use       = d.readInt();
                gtxHeader.imageSize = d.readInt();
                gtxHeader.imagePtr  = d.readInt();
                gtxHeader.mipSize   = d.readInt();
                gtxHeader.mipPtr    = d.readInt();
                gtxHeader.tileMode  = d.readInt();
                gtxHeader.swizzle   = d.readInt();
                gtxHeader.alignment = d.readInt();
                gtxHeader.pitch     = d.readInt();

                //mipOffsets[0] is not in this list and is simply the start of the data (dataOffset)
                //mipOffsets[1] is relative to the start of the data (dataOffset + mipOffsets[1])
                //Other mipOffsets are relative to mipOffset[1] (dataOffset + mipOffsets[1] + mipOffsets[i])
                int[] mipOffsets = new int[mipmapCount];
                mipOffsets[0] = 0;
                for (byte mipLevel = 1; mipLevel < mipmapCount; ++mipLevel)
                {
                    mipOffsets[mipLevel] = 0;
                    mipOffsets[mipLevel] = mipOffsets[1] + d.readInt();
                }

                for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                {
                    tex.surfaces.Add(new TextureSurface());
                }

                int w = tex.Width, h = tex.Height;
                for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                {
                    int p = gtxHeader.pitch / (gtxHeader.width / w);

                    int size;
                    if (mipmapCount == 1)
                    {
                        size = imageSize;
                    }
                    else if (mipLevel + 1 == mipmapCount)
                    {
                        size = (mipSize + mipOffsets[1]) - mipOffsets[mipLevel];
                    }
                    else
                    {
                        size = mipOffsets[mipLevel + 1] - mipOffsets[mipLevel];
                    }

                    size /= surfaceCount;

                    for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                    {
                        gtxHeader.data = d.getSection(dataOffset + mipOffsets[mipLevel] + (size * surfaceLevel), size);

                        //Real size
                        //Leave the below line commented for now because it breaks RGBA textures
                        //size = ((w + 3) >> 2) * ((h + 3) >> 2) * (GTX.getBPP(gtxHeader.format) / 8);
                        if (size < (GTX.getBPP(gtxHeader.format) / 8))
                        {
                            size = (GTX.getBPP(gtxHeader.format) / 8);
                        }

                        byte[] deswiz = GTX.swizzleBC(
                            gtxHeader.data,
                            w,
                            h,
                            gtxHeader.format,
                            gtxHeader.tileMode,
                            p,
                            gtxHeader.swizzle
                            );
                        tex.surfaces[surfaceLevel].mipmaps.Add(new FileData(deswiz).getSection(0, size));
                    }

                    w /= 2;
                    h /= 2;

                    if (w < 1)
                    {
                        w = 1;
                    }
                    if (h < 1)
                    {
                        h = 1;
                    }
                }

                headerPtr += headerSize;

                Nodes.Add(tex);
            }
        }
示例#6
0
        public void ReadNTP3(FileData d)
        {
            d.seek(0x4);

            Version = d.readUShort();
            ushort count = d.readUShort();

            if (Version == 0x100)
            {
                count -= 1;
            }

            d.skip(0x8);
            int headerPtr = 0x10;

            for (ushort i = 0; i < count; ++i)
            {
                d.seek(headerPtr);

                NutTexture tex = new NutTexture();
                tex.isDds = true;
                tex.pixelInternalFormat = PixelInternalFormat.Rgba32ui;

                int totalSize = d.readInt();
                d.skip(4);
                int dataSize   = d.readInt();
                int headerSize = d.readUShort();
                d.skip(2);

                //It might seem that mipmapCount and pixelFormat would be shorts, but they're bytes because they stay in the same place regardless of endianness
                d.skip(1);
                byte mipmapCount = d.readByte();
                d.skip(1);
                tex.setPixelFormatFromNutFormat(d.readByte());
                tex.Width  = d.readUShort();
                tex.Height = d.readUShort();
                d.skip(4);
                uint caps2 = d.readUInt();

                bool isCubemap    = false;
                byte surfaceCount = 1;
                if ((caps2 & (uint)DDS.DDSCAPS2.CUBEMAP) == (uint)DDS.DDSCAPS2.CUBEMAP)
                {
                    //Only supporting all six faces
                    if ((caps2 & (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES) == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
                    {
                        isCubemap    = true;
                        surfaceCount = 6;
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported cubemap face amount for texture {i} with hash 0x{tex.HashId:X}. Six faces are required.");
                    }
                }

                int dataOffset = d.readInt() + headerPtr;
                d.readInt();
                d.readInt();
                d.readInt();

                //The size of a single cubemap face (discounting mipmaps). I don't know why it is repeated. If mipmaps are present, this is also specified in the mipSize section anyway.
                int cmapSize1 = 0;
                int cmapSize2 = 0;
                if (isCubemap)
                {
                    cmapSize1 = d.readInt();
                    cmapSize2 = d.readInt();
                    d.skip(8);
                }

                int[] mipSizes = new int[mipmapCount];
                if (mipmapCount == 1)
                {
                    if (isCubemap)
                    {
                        mipSizes[0] = cmapSize1;
                    }
                    else
                    {
                        mipSizes[0] = dataSize;
                    }
                }
                else
                {
                    for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                    {
                        mipSizes[mipLevel] = d.readInt();
                    }
                    d.align(0x10);
                }

                d.skip(0x10); //eXt data - always the same

                d.skip(4);    //GIDX
                d.readInt();  //Always 0x10
                tex.HashId = d.readInt();
                d.skip(4);    // padding align 8

                if (Version == 0x100)
                {
                    dataOffset = d.pos();
                }

                for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                {
                    TextureSurface surface = new TextureSurface();
                    for (byte mipLevel = 0; mipLevel < mipmapCount; ++mipLevel)
                    {
                        byte[] texArray = d.getSection(dataOffset, mipSizes[mipLevel]);
                        surface.mipmaps.Add(texArray);
                        dataOffset += mipSizes[mipLevel];
                    }
                    tex.surfaces.Add(surface);
                }

                if (tex.getNutFormat() == 14 || tex.getNutFormat() == 17)
                {
                    tex.SwapChannelOrderUp();
                }

                headerPtr += headerSize;

                Nodes.Add(tex);
            }
        }
示例#7
0
        public DDS(FileData d)
        {
            d.Endian = System.IO.Endianness.Little;

            d.seek(0);
            if (d.readUInt() != magic)
            {
                MessageBox.Show("The file does not appear to be a valid DDS file.");
            }

            header                   = new Header();
            header.size              = d.readUInt();
            header.flags             = d.readUInt();
            header.height            = d.readUInt();
            header.width             = d.readUInt();
            header.pitchOrLinearSize = d.readUInt();
            header.depth             = d.readUInt();
            header.mipmapCount       = d.readUInt();
            header.reserved1         = new uint[11];
            for (int i = 0; i < 11; ++i)
            {
                header.reserved1[i] = d.readUInt();
            }

            header.ddspf.size        = d.readUInt();
            header.ddspf.flags       = d.readUInt();
            header.ddspf.fourCC      = d.readUInt();
            header.ddspf.RGBBitCount = d.readUInt();
            header.ddspf.RBitMask    = d.readUInt();
            header.ddspf.GBitMask    = d.readUInt();
            header.ddspf.BBitMask    = d.readUInt();
            header.ddspf.ABitMask    = d.readUInt();

            header.caps      = d.readUInt();
            header.caps2     = d.readUInt();
            header.caps3     = d.readUInt();
            header.caps4     = d.readUInt();
            header.reserved2 = d.readUInt();

            d.seek((int)(4 + header.size));
            bdata = d.read(d.size() - d.pos());
        }
示例#8
0
        public void ReadNTWU(FileData d)
        {
            d.seek(0x4);

            Version = d.readUShort();
            ushort count = d.readUShort();

            d.skip(0x8);
            int headerPtr = 0x10;

            for (ushort i = 0; i < count; ++i)
            {
                d.seek(headerPtr);

                NutTexture tex = new NutTexture();
                tex.type = PixelInternalFormat.Rgba32ui;

                int totalSize = d.readInt();
                d.skip(4);
                int dataSize   = d.readInt();
                int headerSize = d.readUShort();
                d.skip(2);

                d.skip(1);
                byte mipMapCount = d.readByte();
                d.skip(1);
                tex.setPixelFormatFromNutFormat(d.readByte());
                tex.Width  = d.readUShort();
                tex.Height = d.readUShort();
                d.readInt(); //Always 1?
                uint caps2 = d.readUInt();

                bool isCubemap    = false;
                byte surfaceCount = 1;
                if ((caps2 & (uint)DDS.DDSCAPS2.CUBEMAP) == (uint)DDS.DDSCAPS2.CUBEMAP)
                {
                    //Only supporting all six faces
                    if ((caps2 & (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES) == (uint)DDS.DDSCAPS2.CUBEMAP_ALLFACES)
                    {
                        isCubemap    = true;
                        surfaceCount = 6;
                    }
                    else
                    {
                        throw new NotImplementedException($"Unsupported cubemap face amount for texture {i} with hash 0x{tex.HASHID:X}. Six faces are required.");
                    }
                }

                int dataOffset      = d.readInt() + headerPtr;
                int mipDataOffset   = d.readInt() + headerPtr;
                int gtxHeaderOffset = d.readInt() + headerPtr;
                d.readInt();

                int cmapSize1 = 0;
                int cmapSize2 = 0;
                if (isCubemap)
                {
                    cmapSize1 = d.readInt();
                    cmapSize2 = d.readInt();
                    d.skip(8);
                }

                int imageSize = 0; //Total size of first mipmap of every surface
                int mipSize   = 0; //Total size of mipmaps other than the first of every surface
                if (mipMapCount == 1)
                {
                    if (isCubemap)
                    {
                        imageSize = cmapSize1;
                    }
                    else
                    {
                        imageSize = dataSize;
                    }
                }
                else
                {
                    imageSize = d.readInt();
                    mipSize   = d.readInt();
                    d.skip((mipMapCount - 2) * 4);
                    d.align(0x10);
                }

                d.skip(0x10); //eXt data - always the same

                d.skip(4);    //GIDX
                d.readInt();  //Always 0x10
                tex.HASHID = d.readInt();
                d.skip(4);    // padding align 8

                d.seek(gtxHeaderOffset);
                GTX.GX2Surface gtxHeader = new GTX.GX2Surface();

                gtxHeader.dim       = d.readInt();
                gtxHeader.width     = d.readInt();
                gtxHeader.height    = d.readInt();
                gtxHeader.depth     = d.readInt();
                gtxHeader.numMips   = d.readInt();
                gtxHeader.format    = d.readInt();
                gtxHeader.aa        = d.readInt();
                gtxHeader.use       = d.readInt();
                gtxHeader.imageSize = d.readInt();
                gtxHeader.imagePtr  = d.readInt();
                gtxHeader.mipSize   = d.readInt();
                gtxHeader.mipPtr    = d.readInt();
                gtxHeader.tileMode  = d.readInt();
                gtxHeader.swizzle   = d.readInt();
                gtxHeader.alignment = d.readInt();
                gtxHeader.pitch     = d.readInt();

                //mipOffsets[0] is not in this list and is simply the start of the data (dataOffset)
                //mipOffsets[1] is relative to the start of the data (dataOffset + mipOffsets[1])
                //Other mipOffsets are relative to mipOffset[1] (dataOffset + mipOffsets[1] + mipOffsets[i])
                int[] mipOffsets = new int[mipMapCount];
                mipOffsets[0] = 0;
                for (byte mipLevel = 1; mipLevel < mipMapCount; ++mipLevel)
                {
                    mipOffsets[mipLevel] = 0;
                    mipOffsets[mipLevel] = mipOffsets[1] + d.readInt();
                }

                for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                {
                    tex.surfaces.Add(new TextureSurface());
                }

                int w = tex.Width, h = tex.Height;
                for (byte mipLevel = 0; mipLevel < mipMapCount; ++mipLevel)
                {
                    int p = gtxHeader.pitch / (gtxHeader.width / w);

                    int size;
                    if (mipMapCount == 1)
                    {
                        size = imageSize;
                    }
                    else if (mipLevel + 1 == mipMapCount)
                    {
                        size = (mipSize + mipOffsets[1]) - mipOffsets[mipLevel];
                    }
                    else
                    {
                        size = mipOffsets[mipLevel + 1] - mipOffsets[mipLevel];
                    }

                    size /= surfaceCount;

                    for (byte surfaceLevel = 0; surfaceLevel < surfaceCount; ++surfaceLevel)
                    {
                        gtxHeader.data = d.getSection(dataOffset + mipOffsets[mipLevel] + (size * surfaceLevel), size);

                        //Real size
                        //Leave the below line commented for now because it breaks RGBA textures
                        //size = ((w + 3) >> 2) * ((h + 3) >> 2) * (GTX.getBPP(gtxHeader.format) / 8);
                        if (size < (GTX.getBPP(gtxHeader.format) / 8))
                        {
                            size = (GTX.getBPP(gtxHeader.format) / 8);
                        }

                        byte[] deswiz = GTX.swizzleBC(
                            gtxHeader.data,
                            w,
                            h,
                            gtxHeader.format,
                            gtxHeader.tileMode,
                            p,
                            gtxHeader.swizzle
                            );
                        tex.surfaces[surfaceLevel].mipmaps.Add(new FileData(deswiz).getSection(0, size));
                    }

                    w /= 2;
                    h /= 2;

                    if (w < 1)
                    {
                        w = 1;
                    }
                    if (h < 1)
                    {
                        h = 1;
                    }
                }

                headerPtr += headerSize;

                Nodes.Add(tex);
            }

            RefreshGlTexturesByHashId();

            //Console.WriteLine("\tMIP: " + size.ToString("x") + " " + dataOffset.ToString("x") + " " + mipSize.ToString("x") + " " + p + " " + (size == 0 ? ds + dataSize - dataOffset : size));

            //Console.WriteLine(tex.id.ToString("x") + " " + dataOffset.ToString("x") + " " + mipSize.ToString("x") + " " + p + " " + swizzle);
            //Console.WriteLine((tex.width >> mipLevel) + " " + (tex.height >> mipLevel));

            //File.WriteAllBytes("C:\\s\\Smash\\extract\\data\\fighter\\duckhunt\\model\\body\\mip1.bin", bytearray);

            //Console.WriteLine(GL.GetError());

            /*int j = 0;
             * foreach(byte[] b in textures[0].mipmaps)
             * {
             *  if (j == 3)
             *  {
             *      for(int w = 3; w < 8; w++)
             *      {
             *          for (int p = 3; p < 6; p++)
             *          {
             *              byte[] deswiz = GTX.swizzleBC(
             *                  b,
             *                  (int)Math.Pow(2, w),
             *                  64,
             *                  51,
             *                  4,
             *                   (int)Math.Pow(2, p),
             *                  197632
             *              );
             *              File.WriteAllBytes("C:\\s\\Smash\\extract\\data\\fighter\\duckhunt\\model\\body\\chunk_" + (int)Math.Pow(2, p) + "_" + (int)Math.Pow(2, w), deswiz);
             *          }
             *      }
             *
             *  }
             *  j++;
             * }*/
        }