Ejemplo n.º 1
0
        //Parse info help from
        //https://github.com/Joschuka/fmt_g1m/blob/master/Noesis/plugins/python/fmt_g1m.py
        public void Read(FileReader reader)
        {
            reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;

            long   StartPos = reader.Position;
            string Magic    = reader.ReadString(4);

            if (Magic == "GT1G")
            {
                reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
            }
            else
            {
                reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
            }

            IsBigEndian = reader.IsBigEndian;

            if (Magic == "GT1G")
            {
                Platform = GT1Platform.Switch;
            }
            else
            {
                Platform = GT1Platform.WiiU;
            }

            string Version      = reader.ReadString(4);
            uint   FileSize     = reader.ReadUInt32();
            uint   DataOffset   = reader.ReadUInt32();
            uint   TextureCount = reader.ReadUInt32();

            PlatformID = reader.ReadUInt32();
            uint unk2 = reader.ReadUInt32();

            uint[] unk3s = reader.ReadUInt32s((int)TextureCount);

            for (int i = 0; i < TextureCount; i++)
            {
                reader.SeekBegin(StartPos + DataOffset + (i * 4));

                uint InfoOffset = reader.ReadUInt32();

                reader.SeekBegin(DataOffset + InfoOffset);

                byte mipSys   = reader.ReadByte();
                byte format   = reader.ReadByte();
                byte texDims  = reader.ReadByte();
                byte unknown3 = reader.ReadByte(); //1
                byte unknown4 = reader.ReadByte(); //0
                byte unknown5 = reader.ReadByte(); //1
                reader.ReadByte();
                byte flags = reader.ReadByte();

                if (reader.ByteOrder == Syroot.BinaryData.ByteOrder.LittleEndian)
                {
                    mipSys  = SwapEndianByte(mipSys);
                    texDims = SwapEndianByte(texDims);
                }

                uint Width  = (uint)Math.Pow(2, texDims / 16);
                uint Height = (uint)Math.Pow(2, texDims % 16);
                if (flags > 0)
                {
                    var extSize = reader.ReadInt32();
                    if (extSize < 0xC || extSize > 0x14)
                    {
                        throw new Exception("Extra texture data is not between 0xC and 0x14 Bytes!!");
                    }

                    uint param1 = reader.ReadUInt32();
                    uint param2 = reader.ReadUInt32();

                    if (extSize >= 0x10)
                    {
                        Width = reader.ReadUInt32();
                    }
                    if (extSize >= 0x14)
                    {
                        Height = reader.ReadUInt32();
                    }
                }

                GITextureWrapper tex = new GITextureWrapper(this);
                tex.ImageKey         = "texture";
                tex.SelectedImageKey = tex.ImageKey;
                tex.Text             = $"Texture_{i}";
                tex.Width            = Width;
                tex.Height           = Height;
                tex.MipCount         = (uint)mipSys >> 4;
                uint texSys = (uint)mipSys & 0xF;

                uint textureSize = 0;
                uint mortonWidth = 0;
                switch (format)
                {
                case 0x00:     //ABGR
                case 0x01:     //BGRA 32 bit (no mip maps)
                case 0x09:
                    tex.Format = TEX_FORMAT.R8G8B8A8_UNORM;
                    break;

                case 0x34:
                    tex.Format  = TEX_FORMAT.RGB565;
                    textureSize = Width * Height * 2;
                    break;

                case 0x02:
                case 0x06:
                case 0x3C:
                case 0x3D:
                case 0x59:
                case 0x60:     //Swizzled
                    tex.Format = TEX_FORMAT.BC1_UNORM;
                    break;

                case 0x10:
                    tex.Format  = TEX_FORMAT.BC1_UNORM;
                    mortonWidth = 0x4;
                    break;

                case 0x12:
                    tex.Format  = TEX_FORMAT.BC3_UNORM;
                    mortonWidth = 0x8;
                    break;

                case 0x36:
                    tex.Format  = TEX_FORMAT.B4G4R4A4_UNORM;
                    textureSize = Width * Height * 2;
                    break;

                case 0x3:
                case 0x7:
                case 0x8:
                case 0x5B:
                case 0x62:     //bc1 swizzled
                    tex.Format = TEX_FORMAT.BC3_UNORM;
                    break;

                case 0x5C:
                    tex.Format = TEX_FORMAT.BC4_UNORM;
                    break;

                case 0x5D:     //DXT5 swizzled or ATI2
                    tex.Format = TEX_FORMAT.BC5_UNORM;
                    break;

                case 0x5E:
                    tex.Format = TEX_FORMAT.BC6H_UF16;     //Uses cubemaps
                    break;

                case 0x5F:
                    tex.Format = TEX_FORMAT.BC7_UNORM;
                    break;

                case 0xF:
                    textureSize = Width * Height;
                    tex.Format  = TEX_FORMAT.A8_UNORM;
                    break;

                case 0x56:
                    tex.Format  = TEX_FORMAT.ETC1_UNORM;
                    textureSize = Width * Height % 2;
                    break;

                case 0x6F:
                    tex.Format  = TEX_FORMAT.ETC1_UNORM;
                    textureSize = Width * Height;
                    break;

                default:
                    throw new Exception("Unsupported format! " + format.ToString("x"));
                }

                if (textureSize == 0)
                {
                    textureSize = (Width * Height * STGenericTexture.GetBytesPerPixel(tex.Format)) / 8;
                }

                if (format == 0x09)
                {
                    textureSize = (Width * Height * 64) / 8;
                }
                if (format == 0x01)
                {
                    textureSize = (Width * Height * 32) / 8;
                    tex.Parameters.DontSwapRG = true;
                }

                tex.ImageData = reader.ReadBytes((int)textureSize);
                Textures.Add(tex);
            }
        }
Ejemplo n.º 2
0
        public void Read(FileReader reader)
        {
            reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;

            Text = FileName;

            long   StartPos = reader.Position;
            string Magic    = reader.ReadString(4);

            if (Magic == "GT1G")
            {
                reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
            }
            else
            {
                reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
            }

            if (Magic == "GT1G")
            {
                Platform = GT1Platform.Switch;
            }
            else
            {
                Platform = GT1Platform.WiiU;
            }

            string Version      = reader.ReadString(4);
            uint   FileSize     = reader.ReadUInt32();
            uint   DataOffset   = reader.ReadUInt32();
            uint   TextureCount = reader.ReadUInt32();
            uint   unk          = reader.ReadUInt32();
            uint   unk2         = reader.ReadUInt32();

            uint[] unk3s = reader.ReadUInt32s((int)TextureCount);

            for (int i = 0; i < TextureCount; i++)
            {
                reader.SeekBegin(StartPos + DataOffset + (i * 4));

                uint InfoOffset = reader.ReadUInt32();

                reader.SeekBegin(DataOffset + InfoOffset);

                byte numMips     = reader.ReadByte();
                byte format      = reader.ReadByte();
                byte texDims     = reader.ReadByte();
                byte unknown3    = reader.ReadByte(); //1
                byte unknown4    = reader.ReadByte(); //0
                byte unknown5    = reader.ReadByte(); //1
                byte unknown6    = reader.ReadByte(); //12
                byte extraHeader = reader.ReadByte();

                if (reader.ByteOrder == Syroot.BinaryData.ByteOrder.LittleEndian)
                {
                    numMips     = SwapEndianByte(numMips);
                    texDims     = SwapEndianByte(texDims);
                    extraHeader = SwapEndianByte(extraHeader);
                }

                if (extraHeader == 1)
                {
                    var extSize = reader.ReadInt32();
                    var ext     = reader.ReadBytes(extSize - 4);
                }

                uint Width  = (uint)Math.Pow(2, texDims / 16);
                uint Height = (uint)Math.Pow(2, texDims % 16);

                GITexture tex = new GITexture(this);
                tex.ImageKey         = "texture";
                tex.SelectedImageKey = tex.ImageKey;
                tex.Text             = $"Texture {i}  {format.ToString("x")}";
                tex.Width            = Width;
                tex.Height           = Height;
                tex.MipCount         = numMips;

                switch (format)
                {
                case 0x00:     //ABGR
                case 0x01:     //BGRA 32 bit (no mip maps)
                case 0x02:     //RGBA 32 bit
                case 0x09:
                    tex.Format = TEX_FORMAT.R8G8B8A8_UNORM;
                    break;

                case 0x06:
                case 0x10:     //PC and xbox (swizzled)
                case 0x59:
                case 0x60:     //Swizzled
                    tex.Format = TEX_FORMAT.BC1_UNORM;
                    break;

                case 0x7:
                case 0x8:
                case 0x12:     //PC and xbox (swizzled)
                case 0x5B:
                case 0x62:     //bc1 swizzled
                    tex.Format = TEX_FORMAT.BC3_UNORM;
                    break;

                case 0x5C:
                    tex.Format = TEX_FORMAT.BC4_UNORM;
                    break;

                case 0x5D:     //DXT5 swizzled or ATI2
                    tex.Format = TEX_FORMAT.BC5_UNORM;
                    break;

                case 0x5E:
                    tex.Format = TEX_FORMAT.BC6H_UF16;     //Uses cubemaps
                    break;

                case 0x5F:
                    tex.Format = TEX_FORMAT.BC7_UNORM;
                    break;

                default:
                    throw new Exception("Unsupported format! " + format.ToString("x"));
                }

                uint textureSize = (Width * Height * STGenericTexture.GetBytesPerPixel(tex.Format)) / 8;
                if (format == 0x09)
                {
                    textureSize = (Width * Height * 64) / 8;
                }
                if (format == 0x01)
                {
                    textureSize = (Width * Height * 32) / 8;
                    tex.Parameters.DontSwapRG = true;
                }

                tex.ImageData = reader.ReadBytes((int)textureSize);
                Nodes.Add(tex);
            }
        }