Exemplo n.º 1
0
        public static string[] ReadZeroTerminatedStringArrays(LimitedReader partialReader, bool withOffsets, out Dictionary <int, string>?offsets)
        {
            List <string> textures = new();

            offsets = withOffsets ? new() : null;
            var startOffset = partialReader.Offset;

            while (!partialReader.IsFinished())
            {
                int start = partialReader.Offset;
                while (partialReader.ReadByte() != 0)
                {
                    ;
                }
                int end = partialReader.Offset - 1;

                if (end == start && partialReader.IsFinished())
                {
                    break;
                }

                partialReader.Offset = start;
                var textureNameBytes = partialReader.ReadBytes(end - start);
                var textureName      = System.Text.Encoding.ASCII.GetString(textureNameBytes);
                textures.Add(textureName);
                if (withOffsets)
                {
                    offsets ![start - startOffset] = textureName;
Exemplo n.º 2
0
        public BLP(byte[] bytes, int start, int length)
        {
            var reader = new MemoryBinaryReader(bytes, start, length);

            Header = new BLPHeader(reader);
            uint w = Header.Width;
            uint h = Header.Height;

            Data = new Rgba32[Header.MipCount][];

            int mipLevel;

            for (mipLevel = 0; mipLevel < Header.MipCount; ++mipLevel)
            {
                reader.Offset = (int)Header.GetMipOffset(mipLevel);
                var mipReader = new LimitedReader(reader, (int)Header.GetMipSize(mipLevel));

                if (Header.ColorEncoding == ColorEncoding.Palette)
                {
                    uint len = w * h;
                    Data[mipLevel] = new Rgba32[w * h];
                    for (int j = 0; j < len; j++)
                    {
                        var b = mipReader.ReadByte();

                        var color  = Header.PaletteBGRA ![b];
Exemplo n.º 3
0
        private WorldMapObjectPlacementData[] ReadWorldMapObjectPlacementData(LimitedReader reader, string[]?names)
        {
            Debug.Assert(names != null);
            int i = 0;

            WorldMapObjectPlacementData[] data = new WorldMapObjectPlacementData[reader.Size / 0x40];
            while (!reader.IsFinished())
            {
                data[i++] = new WorldMapObjectPlacementData(reader, names);
            }
            return(data);
        }
Exemplo n.º 4
0
        private M2PlacementData[] ReadM2PlacementData(LimitedReader reader, string[]?names)
        {
            Debug.Assert(names != null);
            int i = 0;

            M2PlacementData[] data = new M2PlacementData[reader.Size / 0x24];
            while (!reader.IsFinished())
            {
                data[i++] = new M2PlacementData(reader, names);
            }
            return(data);
        }
Exemplo n.º 5
0
        public ADT(IBinaryReader reader)
        {
            string[]? worldMapObjectsIds = null;
            string[]? m2Ids = null;
            Dictionary <int, string>?wmosNameOffsets = null;
            Dictionary <int, string>?m2NameOffsets   = null;
            int chunkId = 0;

            while (!reader.IsFinished())
            {
                var chunkName = reader.ReadChunkName();
                var size      = reader.ReadInt32();

                var offset = reader.Offset;

                var partialReader = new LimitedReader(reader, size);

                if (chunkName == "MTEX")
                {
                    Textures = ChunkedUtils.ReadZeroTerminatedStringArrays(partialReader, false, out _);
                }
                else if (chunkName == "MWMO")
                {
                    ChunkedUtils.ReadZeroTerminatedStringArrays(partialReader, true, out wmosNameOffsets);
                }
                else if (chunkName == "MWID")
                {
                    worldMapObjectsIds = ReadNameOffsets(partialReader, wmosNameOffsets);
                }
                else if (chunkName == "MODF")
                {
                    WorldMapObjects = ReadWorldMapObjectPlacementData(partialReader, worldMapObjectsIds);
                }
                else if (chunkName == "MMDX")
                {
                    ChunkedUtils.ReadZeroTerminatedStringArrays(partialReader, true, out m2NameOffsets);
                }
                else if (chunkName == "MMID")
                {
                    m2Ids = ReadNameOffsets(partialReader, m2NameOffsets);
                }
                else if (chunkName == "MDDF")
                {
                    M2Objects = ReadM2PlacementData(partialReader, m2Ids);
                }
                else if (chunkName == "MCNK")
                {
                    Chunks[chunkId++] = new AdtChunk(partialReader);
                }

                reader.Offset = offset + size;
            }
        }
Exemplo n.º 6
0
        private string[] ReadNameOffsets(LimitedReader reader, Dictionary <int, string>?wmosNameOffsets)
        {
            Debug.Assert(wmosNameOffsets != null);
            int i = 0;

            string[] names = new string[reader.Size / 4];
            while (!reader.IsFinished())
            {
                names[i++] = wmosNameOffsets[reader.ReadInt32()];
            }

            return(names);
        }
Exemplo n.º 7
0
        public T Deserialize <T>() where T : new()
        {
            var s_Resource = new T();

            m_Stream.Skip(4); // Magic (BIN1)
            m_Stream.Skip(1); // Unknown (always 0?)

            Alignment = m_Stream.ReadUByte();
            var s_SegmentCount = m_Stream.ReadUByte();

            m_Stream.Skip(1); // Unknown (always 0?)

            var s_DataSize = m_Stream.ReadUInt32Flipped();

            m_Stream.Skip(4); // Unknown (maybe alignment?)

            var s_Data = m_Stream.ReadBytes((int)s_DataSize);

            using var s_DataReader = new ZHMStream(new MemoryStream(s_Data));

            for (var i = 0; i < s_SegmentCount; ++i)
            {
                var s_SegmentType = m_Stream.ReadUInt32();
                var s_SegmentSize = m_Stream.ReadUInt32();

                Console.WriteLine($"Found segment {i} with {s_SegmentSize} bytes of data. Type: {s_SegmentType:X08}.");

                if (SegmentParsers.TryGetValue(s_SegmentType, out var s_Parser))
                {
                    using var s_SegmentReader = new LimitedReader(m_Stream, s_SegmentSize, false);
                    s_Parser.ParseSegment(s_SegmentReader, s_DataReader);
                }
                else
                {
                    throw new Exception($"Could not find a segment parser for segment of type {s_SegmentType:X08}.");
                }
            }

            Console.WriteLine($"Read {s_SegmentCount} segments with {m_Stream.BaseStream.Length - m_Stream.BaseStream.Position} bytes left to read.");

            return(s_Resource);
        }
Exemplo n.º 8
0
        public WDT(IBinaryReader reader)
        {
            int chunkId = 0;
            Dictionary <int, string>?mwmosNameOffsets = null;

            while (!reader.IsFinished())
            {
                var chunkName = reader.ReadChunkName();
                var size      = reader.ReadInt32();

                var offset = reader.Offset;

                var partialReader = new LimitedReader(reader, size);

                if (chunkName == "MVER")
                {
                    Version = reader.ReadUInt32();
                }
                else if (chunkName == "MPHD")
                {
                    Header = WDTHeader.Read(partialReader);
                }
                else if (chunkName == "MAIN")
                {
                    Chunks[chunkId++] = new WDTChunk(partialReader);
                }
                else if (chunkName == "MWMO")
                {
                    Mwmo = ChunkedUtils.ReadZeroTerminatedStringArrays(partialReader, true, out mwmosNameOffsets)[0];
                }
                else if (chunkName == "MODF")
                {
                    WorldMapObject = MODF.Read(partialReader);
                }
                reader.Offset = offset + size;
            }
        }