Пример #1
0
        public void ReadNTWU(FileData d)
        {
            d.skip(0x02);
            int count = d.readShort();

            d.skip(0x10);
            int headerPtr       = d.pos();
            int dataPtr         = 0;
            int gtxHeaderOffset = 0;

            for (int i = 0; i < count; i++)
            {
                NUD_Texture tex = new NUD_Texture();
                tex.type = PixelInternalFormat.Rgba32ui;

                d.seek(headerPtr);
                int totalSize  = d.readInt();
                int headerSize = d.readShort();
                int numMips    = d.readInt();
                tex.setPixelFormatFromNutFormat(d.readShort());
                tex.width  = d.readShort();
                tex.height = d.readShort();

                d.skip(8); // mipmaps and padding
                int dataOffset = d.readInt() + dataPtr + 0x10;

                headerPtr += headerSize;
                dataPtr   += headerSize;

                d.skip(0x04);
                if (i == 0)
                {
                    gtxHeaderOffset = d.readInt() + 0x10;
                }
                else
                {
                    gtxHeaderOffset += 0x80;
                    d.skip(0x04);
                }

                d.skip(0x04);
                d.skip(headerSize - 0x50);

                d.skip(0x18);
                tex.id = d.readInt();

                d.seek(gtxHeaderOffset);
                d.skip(0x04); // dim
                d.skip(0x04); // width
                d.skip(0x04); // height
                d.skip(0x04); // depth
                d.skip(0x04); // numMips
                int format = d.readInt();
                d.skip(0x04); // aa
                d.skip(0x04); // use
                int imageSize = d.readInt();
                d.skip(0x04); // imagePtr
                d.skip(0x04); // mipSize
                d.skip(0x04); // mipPtr
                int tileMode = d.readInt();
                int swizzle  = d.readInt();
                d.skip(0x04); // alignment
                int pitch = d.readInt();

                for (int mipLevel = 0; mipLevel < numMips; mipLevel++)
                {
                    // Maybe this is the problem?
                    int mipSize = imageSize >> (mipLevel * 2);

                    //if (mipLevel == 0)
                    {
                        tex.mipmaps.Add(GTX.swizzleBC(
                                            d.getSection(dataOffset, mipSize),
                                            (tex.width >> mipLevel),
                                            (tex.height >> mipLevel),
                                            format,
                                            tileMode,
                                            pitch,
                                            swizzle
                                            ));
                    }

                    dataOffset += mipSize;
                }

                textures.Add(tex);
            }

            foreach (var tex in textures)
            {
                if (!draw.ContainsKey(tex.id))
                {
                    draw.Add(tex.id, loadImage(tex));
                }
            }
        }
Пример #2
0
        public void ReadNTP3(FileData d)
        {
            d.skip(0x2);
            int count = d.readShort();

            d.skip(0x10);

            int headerPtr = d.pos();
            int dataPtr   = 0;

            for (int i = 0; i < count; i++)
            {
                NUD_Texture tex = new NUD_Texture();
                tex.type = PixelInternalFormat.Rgba32ui;

                d.seek(headerPtr);
                int totalSize  = d.readInt();
                int headerSize = d.readShort();
                headerPtr += headerSize;

                int numMips = d.readInt();
                tex.setPixelFormatFromNutFormat(d.readShort());
                tex.width  = d.readShort();
                tex.height = d.readShort();

                d.skip(8); // mipmaps and padding
                int dataOffset = d.readInt() + dataPtr + 0x10;
                d.skip(0x0C);

                int[] mipSizes = new int[numMips];

                if (headerSize == 0x50)
                {
                    mipSizes[0] = totalSize;
                }
                else
                {
                    for (int j = 0; j < numMips; j++)
                    {
                        mipSizes[j] = d.readInt();
                    }
                }

                // NOTE: I have no clue what these other header sizes are.
                // pls send help.
                if (headerSize > 0x60)
                {
                    d.skip(headerSize - 0x60);
                }

                d.skip(0x18);
                tex.id = d.readInt();
                for (int miplevel = 0; miplevel < numMips; miplevel++)
                {
                    byte[] texArray = d.getSection(dataOffset, mipSizes[miplevel]);

                    if (tex.getNutFormat() == 14)
                    {
                        byte[] oldArray = texArray;
                        for (int pos = 0; pos < mipSizes[miplevel]; pos += 4)
                        {
                            for (int p = 0; p < 4; p++)
                            {
                                if (p == 0)
                                {
                                    texArray[pos + 3] = oldArray[pos];
                                }
                                else
                                {
                                    texArray[pos + p - 1] = oldArray[pos + p];
                                }
                            }
                        }
                    }
                    tex.mipmaps.Add(texArray);
                    dataOffset += mipSizes[miplevel];
                }

                dataPtr += headerSize;

                textures.Add(tex);
            }

            foreach (var tex in textures)
            {
                if (!draw.ContainsKey(tex.id))
                {
                    draw.Add(tex.id, loadImage(tex));
                }
            }
        }
Пример #3
0
        public void ReadNTP3(FileData d)
        {
            d.skip(0x2);
            int count = d.readShort();

            d.skip(0x8);

            int dataPtr = 0;

            for (int i = 0; i < count; i++)
            {
                Debug.WriteLine(d.pos().ToString("x"));
                NUD_Texture tex = new NUD_Texture();
                tex.type = PixelInternalFormat.Rgba32ui;

                int totalSize = d.readInt();
                d.skip(4); // padding

                int dataSize   = d.readInt();
                int headerSize = d.readShort();
                d.skip(3);
                int numMips = d.readByte();
                Debug.WriteLine(numMips);
                d.skip(1);
                tex.setPixelFormatFromNutFormat(d.readByte());
                tex.width  = d.readShort();
                tex.height = d.readShort();

                d.skip(8); // padding?

                int dataOffset = d.readInt() + dataPtr + 0x10;
                d.skip(0x0C);

                int[] mipSizes = new int[numMips];

                if (numMips == 1)
                {
                    mipSizes[0] = dataSize;
                }
                else
                {
                    for (int j = 0; j < numMips; j++)
                    {
                        mipSizes[j] = d.readInt();
                    }
                }
                d.align(16);

                d.skip(0x18);
                tex.id = d.readInt();
                d.skip(4); // padding align 8

                // add mipmap data
                for (int miplevel = 0; miplevel < numMips; miplevel++)
                {
                    byte[] texArray = d.getSection(dataOffset, mipSizes[miplevel]);
                    tex.mipmaps.Add(texArray);
                    dataOffset += mipSizes[miplevel];
                }

                dataPtr += headerSize;

                if (tex.getNutFormat() == 14 || tex.getNutFormat() == 17)
                {
                    Console.WriteLine("Endian swap");
                    // swap
                    foreach (byte[] mip in tex.mipmaps)
                    {
                        for (int t = 0; t < mip.Length; t += 4)
                        {
                            byte t1 = mip[t];
                            mip[t]     = mip[t + 1];
                            mip[t + 1] = mip[t + 2];
                            mip[t + 2] = mip[t + 3];
                            mip[t + 3] = t1;

                            /*byte t1 = mip[t];
                             * byte t2 = mip[t+1];
                             * mip[t] = mip[t + 3];
                             * mip[t + 1] = mip[t + 2];
                             * mip[t + 2] = t2;
                             * mip[t + 3] = t1;*/
                        }
                    }
                }

                textures.Add(tex);

                /*for (int miplevel = 0; miplevel < numMips; miplevel++)
                 * {
                 *  byte[] texArray = d.getSection(dataOffset, mipSizes[miplevel]);
                 *
                 *  if (tex.getNutFormat() == 14)
                 *  {
                 *      byte[] oldArray = texArray;
                 *      for (int pos = 0; pos < mipSizes[miplevel]; pos+=4)
                 *      {
                 *
                 *          for (int p = 0; p < 4; p++)
                 *          {
                 *              if (p == 0)
                 *                  texArray[pos + 3] = oldArray[pos];
                 *              else
                 *                  texArray[pos + p - 1] = oldArray[pos + p];
                 *          }
                 *
                 *      }
                 *  }
                 *  tex.mipmaps.Add(texArray);
                 *  dataOffset += mipSizes[miplevel];
                 * }*/
            }

            foreach (var tex in textures)
            {
                if (!draw.ContainsKey(tex.id))
                {
                    draw.Add(tex.id, loadImage(tex, true));
                }
            }
        }
Пример #4
0
        public void ReadNTWU(FileData d)
        {
            d.skip(0x02);
            int count = d.readShort();

            d.skip(0x10);
            int headerPtr       = d.pos();
            int dataPtr         = 0;
            int gtxHeaderOffset = 0;

            for (int i = 0; i < count; i++)
            {
                NUD_Texture tex = new NUD_Texture();
                tex.type = PixelInternalFormat.Rgba32ui;

                d.seek(headerPtr);
                int totalSize  = d.readInt();
                int headerSize = d.readShort();
                int numMips    = d.readInt();
                tex.setPixelFormatFromNutFormat(d.readShort());
                tex.width  = d.readShort();
                tex.height = d.readShort();

                d.skip(8); // mipmaps and padding
                int dataOffset = d.readInt() + dataPtr + 0x10;

                headerPtr += headerSize;
                dataPtr   += headerSize;

                d.skip(0x04);
                if (i == 0)
                {
                    gtxHeaderOffset = d.readInt() + 0x10;
                }
                else
                {
                    gtxHeaderOffset += 0x80;
                    d.skip(0x04);
                }

                d.skip(0x04);

                // check for cubemap
                bool cmap = (d.readInt() == d.readInt());
                d.seek(d.pos() - 8);
                if (cmap)
                {
                    Console.WriteLine("cubemap detected");
                }

                d.skip(headerSize - 0x50);

                d.skip(0x18);
                tex.id = d.readInt();

                d.seek(gtxHeaderOffset);
                d.skip(0x04); // dim
                d.skip(0x04); // width
                d.skip(0x04); // height
                d.skip(0x04); // depth
                d.skip(0x04); // numMips
                int format = d.readInt();
                d.skip(0x04); // aa
                d.skip(0x04); // use
                int imageSize = d.readInt();
                d.skip(0x04); // imagePtr
                d.skip(0x04); // mipSize
                d.skip(0x04); // mipPtr
                int tileMode = d.readInt();
                int swizzle  = d.readInt();
                d.skip(0x04); // alignment
                int pitch = d.readInt();

                for (int mipLevel = 0; mipLevel < numMips; mipLevel++)
                {
                    // Maybe this is the problem?
                    int mipSize = imageSize >> (mipLevel * 2);
                    int p       = pitch >> mipLevel;

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

                    //if (cmap) tex.height *= 2;

                    int w = (tex.width >> mipLevel);
                    int h = (tex.height >> mipLevel);

                    //if (mipSize % 0x10 != 0) mipSize += mipSize % 0x10;
                    //if (cmap) mipSize /= 6;

                    //if (p <= 16) p = 64;
                    {
                        tex.mipmaps.Add(GTX.swizzleBC(
                                            d.getSection(dataOffset, mipSize),
                                            w,
                                            h,
                                            format,
                                            tileMode,
                                            p,
                                            swizzle
                                            ));
                    }
                    dataOffset += mipSize;

                    /*if (cmap)
                     * {
                     *  for(int k = 0; k < 5; k++)
                     *  {
                     *      p = pitch >> (mipLevel + k + 1);
                     *      tex.mipmaps.Add(GTX.swizzleBC(
                     *          d.getSection(dataOffset, mipSize),
                     *          w,
                     *          h,
                     *          format,
                     *          tileMode,
                     *          p,
                     *          swizzle
                     *      ));
                     *
                     *      dataOffset += mipSize;
                     *  }
                     * }*/

                    //while (dataOffset % 1024 != 0) dataOffset++;
                    //if (mipSize == 0x4000) dataOffset += 0x400;
                }

                // fix mipmap swizzle for rgba types
                if (tex.getNutFormat() == 14 || tex.getNutFormat() == 17)
                {
                    Console.WriteLine("Endian swap");
                    // swap
                    foreach (byte[] mip in tex.mipmaps)
                    {
                        for (int t = 0; t < mip.Length; t += 4)
                        {
                            /*byte t1 = mip[t];
                             * byte t2 = mip[t+1];
                             * mip[t] = mip[t + 3];
                             * mip[t + 1] = mip[t + 2];
                             * mip[t + 2] = t2;
                             * mip[t + 3] = t1;*/
                        }
                    }
                }

                textures.Add(tex);
            }

            foreach (var tex in textures)
            {
                if (!draw.ContainsKey(tex.id))
                {
                    draw.Add(tex.id, loadImage(tex));
                }
            }
        }
Пример #5
0
        public void ReadNTWU(FileData d)
        {
            d.skip(0x02);
            int count = d.readShort();

            d.skip(0x10);
            int headerPtr       = d.pos();
            int dataPtr         = 0;
            int gtxHeaderOffset = 0;

            for (int i = 0; i < count; i++)
            {
                NUD_Texture tex = new NUD_Texture();
                tex.type = PixelInternalFormat.Rgba32ui;

                d.seek(headerPtr);
                int totalSize  = d.readInt();
                int headerSize = d.readShort();
                int numMips    = d.readInt();
                tex.setPixelFormatFromNutFormat(d.readShort());
                tex.width  = d.readShort();
                tex.height = d.readShort();

                d.skip(8); // mipmaps and padding
                int dataOffset = d.readInt() + dataPtr + 0x10;

                headerPtr += headerSize;
                dataPtr   += headerSize;

                d.skip(0x04);
                if (i == 0)
                {
                    gtxHeaderOffset = d.readInt() + 0x10;
                }
                else
                {
                    gtxHeaderOffset += 0x80;
                    d.skip(0x04);
                }

                d.skip(0x04);

                // check for cubemap
                bool cmap = (d.readInt() == d.readInt());
                d.seek(d.pos() - 8);
                if (cmap)
                {
                    Console.WriteLine("cubemap detected");
                }

                d.skip(headerSize - 0x50);

                d.skip(0x18);
                tex.id = d.readInt();

                Console.WriteLine(gtxHeaderOffset.ToString("x"));
                d.seek(gtxHeaderOffset);
                d.skip(0x04);              // dim
                d.skip(0x04);              // width
                d.skip(0x04);              // height
                d.skip(0x04);              // depth
                d.skip(0x04);              // numMips
                int format = d.readInt();
                d.skip(0x04);              // aa
                d.skip(0x04);              // use
                int imageSize = d.readInt();
                d.skip(0x04);              // imagePtr
                int maxSize = d.readInt(); // mipSize
                d.skip(0x04);              // mipPtr
                int tileMode = d.readInt();
                int swizzle  = d.readInt();
                d.skip(0x04); // alignment
                int pitch = d.readInt();

                int ds   = dataOffset;
                int s1   = 0;
                int size = 0;
                Console.WriteLine(totalSize.ToString("x"));
                for (int mipLevel = 0; mipLevel < numMips; mipLevel++)
                {
                    // Maybe this is the problem?
                    int mipSize = imageSize >> (mipLevel * 2);
                    int p       = pitch >> mipLevel;

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

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

                    //if (cmap) tex.height *= 2;

                    int w = (tex.width >> mipLevel);
                    int h = (tex.height >> mipLevel);

                    {
                        byte[] deswiz = GTX.swizzleBC(
                            d.getSection(dataOffset, d.size() - dataOffset),
                            w,
                            h,
                            format,
                            tileMode,
                            p,
                            swizzle
                            );
                        tex.mipmaps.Add(new FileData(deswiz).getSection(0, mipSize));
                    }
                    if (mipLevel == 0)
                    {
                        s1         = size;
                        dataOffset = ds + size;
                    }
                    else
                    {
                        dataOffset = ds + s1 + size;
                    }
                    //dataOffset += mipSize;

                    /*if (cmap)
                     * {
                     *  for(int k = 0; k < 5; k++)
                     *  {
                     *      p = pitch >> (mipLevel + k + 1);
                     *      tex.mipmaps.Add(GTX.swizzleBC(
                     *          d.getSection(dataOffset, mipSize),
                     *          w,
                     *          h,
                     *          format,
                     *          tileMode,
                     *          p,
                     *          swizzle
                     *      ));
                     *
                     *      dataOffset += mipSize;
                     *  }
                     * }*/

                    //while (dataOffset % 1024 != 0) dataOffset++;
                    //if (mipSize == 0x4000) dataOffset += 0x400;
                }

                textures.Add(tex);
            }

            foreach (var tex in textures)
            {
                if (!draw.ContainsKey(tex.id))
                {
                    draw.Add(tex.id, loadImage(tex, false));
                }

                // redo mipmaps

                /*GL.BindTexture(TextureTarget.Texture2D, draw[tex.id]);
                 * for (int k = 1; k < tex.mipmaps.Count; k++)
                 * {
                 *  tex.mipmaps[k] = new byte[tex.mipmaps[k].Length];
                 *  GCHandle pinnedArray = GCHandle.Alloc(tex.mipmaps[k], GCHandleType.Pinned);
                 *  IntPtr pointer = pinnedArray.AddrOfPinnedObject();
                 *  GL.GetCompressedTexImage(TextureTarget.Texture2D, 0, pointer);
                 *  pinnedArray.Free();
                 * }*/
            }


            //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++;
             * }*/
        }