Exemple #1
0
        public FieldInvoke GetOffsetWork()
        {
            return(new FieldInvoke(
                       (Stream, FromReader, Struct) => {
                XBXHeader Header = Struct;

                uint Count = (Header.EntryLen * Header.EntriesCount);
                if (FromReader)
                {
                    StructReader Reader = new StructReader(Stream);
                    Header.Offsets = new uint[Count];
                    for (uint i = 0; i < Count; i++)
                    {
                        Header.Offsets[i] = Reader.ReadRawType(Const.UINT32);
                    }

                    Header.IsString = new bool[Header.EntryLen];
                    for (uint i = 0; i < Header.EntryLen; i++)
                    {
                        Header.IsString[i] = IsString(Stream, Header.Offsets[i] + Header.StrPos);
                    }
                }
                else
                {
                    for (uint i = 0, x = 0; i < Header.Offsets.Length; i++)
                    {
                        if (!Header.IsString[i % Header.EntryLen])
                        {
                            continue;
                        }

                        Header.Offsets[i] = x;
                        x += (uint)Encoding.GetByteCount(Header.Strings[i]) + 1;
                    }
                    StructWriter Writer = new StructWriter(Stream);
                    for (uint i = 0; i < Count; i++)
                    {
                        Writer.WriteRawType(Const.UINT32, Header.Offsets[i]);
                    }
                }

                return Header;
            }));
        }
Exemple #2
0
        public void Encode(Bitmap Texture, Stream Output, bool CloseStreams = true)
        {
            StructWriter Writer = new StructWriter(Output, (bool)IsBigEnddian);

            Writer.Write(0x2065727574786554);

            if (SteamVersion.Value)
            {
                Writer.Write(0x20202020);

                Writer.Write(0); //0xC, section length
                Writer.WriteRawType(Const.UINT64, SteamUnk);
                Writer.Write(0); //0x18, pnglen
                Writer.WriteRawType(Const.UINT16, (ushort)TexSize.Width);
                Writer.WriteRawType(Const.UINT16, (ushort)TexSize.Height);
            }
            else
            {
                Writer.Write(0); //0x8, blocklen
                Writer.WriteRawType(Const.UINT32, Flags);
                Writer.Write(0); //0x10, pnglen
                Writer.WriteRawType(Const.UINT32, (uint)TexSize.Width);
                Writer.WriteRawType(Const.UINT32, (uint)TexSize.Height);
            }

            if (Tiled)
            {
                Texture = Retile(Texture);
            }
            uint SectionLength;

            if (SteamVersion.Value)
            {
                byte[] Buffer = new byte[Texture.Width * Texture.Height * 4];
                fixed(void *pBuff = &Buffer[0])
                {
                    int   Stride = Texture.Width;
                    uint *pPixel = (uint *)pBuff;

                    unchecked
                    {
                        for (int i = 0; i < Buffer.Length / 4; i++)
                        {
                            int X = i % Stride;
                            int Y = i / Stride;

                            uint ARGB = (uint)Texture.GetPixel(X, Y).ToArgb();

                            //ARGB => ABGR
                            *pPixel++ = (ARGB & 0xFF00FF00) | ((ARGB & 0x00FF0000) >> 8 * 2) | ((ARGB & 0x000000FF) << 8 * 2);
                        }
                    }
                }

                if (Compressed)
                {
                    Buffer = LZSSCompress(Buffer);
                }

                Writer.Write(Buffer);

                SectionLength = (uint)Writer.BaseStream.Position;
                uint TexLen = SectionLength - 0x20;
                Writer.Seek(0xC, 0);
                Writer.WriteRawType(Const.UINT32, SectionLength);
                Writer.Seek(0x18, 0);
                Writer.WriteRawType(Const.UINT32, TexLen);
            }
            else
            {
                Texture.Save(Writer.BaseStream, ImageFormat.Png);
                SectionLength = (uint)Writer.BaseStream.Position;
                uint PngLen = SectionLength - 0x1C;
                Writer.Seek(0x8, 0);
                Writer.WriteRawType(Const.UINT32, SectionLength);
                Writer.Seek(0x10, 0);
                Writer.WriteRawType(Const.UINT32, PngLen);
            }

            Writer.Seek(SectionLength, 0);
            while (Writer.BaseStream.Position % (SteamVersion.Value ? 8 : 4) != 0)
            {
                Writer.Write((byte)0x0);
            }

            StructReader Reader = new StructReader(this.Texture, (bool)IsBigEnddian);

            Reader.Seek(SteamVersion.Value ? 0x0C : 0x08, 0);
            Reader.Seek(Reader.ReadRawType(Const.UINT32), 0);

            while (Reader.BaseStream.Position % (SteamVersion.Value ? 8 : 4) != 0)
            {
                Reader.ReadByte();
            }

            Reader.BaseStream.CopyTo(Writer.BaseStream);
            Writer.Flush();

            if (CloseStreams)
            {
                Writer.Close();
                Output?.Close();
            }
        }