Пример #1
0
 internal static Bitmap LoadRawBitmap(Stream inputStream)
 {
     using (var r = new BinaryFileReader(inputStream))
     {
         var header       = r.ReadT <BitmapHeader>(0x10);
         var frameCount   = header.FrameCount;
         var frameOffsets = r.ReadTArray <BitmapFrameOffset>(frameCount * 0x08, frameCount);
         var frames       = new Texture2DInfo[frameCount];
         for (var i = 0; i < frameCount; i++)
         {
             r.Position = frameOffsets[i].Offset;
             var frame         = r.ReadT <BitmapFrame>(0x14);
             var frameHeight   = (int)frame.height;
             var sizeOfFrame   = 0x14 + frameHeight * 0x04;
             var frameDataSize = (int)(frameHeight * frame.width);
             var bitsPerPixel  = (int)((frameOffsets[i].Size - sizeOfFrame) / frameDataSize);
             var offsets       = r.ReadTArray <uint>(frameHeight * 0x04, frameHeight); // Offset to the data for each row relative to the start of the resource.
             if (offsets[0] == 0xCDCDCDCD)                                             //: unknownFrame
             {
                 continue;
             }
             r.Position = frameOffsets[i].Offset + offsets[0];
             var rawData = r.ReadBytes(frameDataSize * bitsPerPixel);
             frames[i] = bitsPerPixel == 1
                 ? new Texture2DInfo((int)frame.width, (int)frame.height, UnityEngine.TextureFormat.RGBA32, false, rawData).From8BitPallet(GetGlobal8BitPallet(), UnityEngine.TextureFormat.RGBA32)
                 : new Texture2DInfo((int)frame.width, (int)frame.height, UnityEngine.TextureFormat.RGBA32, false, rawData).FromABGR555();
         }
         return(new Bitmap
         {
             Header = header,
             Frames = frames,
         });
     }
 }
Пример #2
0
 public VTEXField(BinaryFileReader r, int dataSize, GameFormat format)
 {
     if (format == GameFormat.TES3)
     {
         TextureIndicesT3 = r.ReadTArray <ushort>(dataSize, dataSize >> 1);
         TextureIndicesT4 = null;
         return;
     }
     TextureIndicesT3 = null;
     TextureIndicesT4 = r.ReadTArray <uint>(dataSize, dataSize >> 2);
 }
Пример #3
0
            public sbyte[] HeightData;      // HeightData

            public VHGTField(BinaryFileReader r, int dataSize)
            {
                ReferenceHeight = r.ReadSingle();
                var count = dataSize - 4 - 3;

                HeightData = r.ReadTArray <sbyte>(count, count);
                //HeightData = new sbyte[count];
                //for (var i = 0; i < HeightData.Length; i++) HeightData[i] = r.ReadSByte();
                r.Skip(3); // Unused
            }
Пример #4
0
            public RNAMField(BinaryFileReader r, int dataSize)
            {
                GridX = r.ReadInt16();
                GridY = r.ReadInt16();
                var referenceCount = r.ReadUInt32();
                var referenceSize  = dataSize - 8;

                Assert(referenceSize >> 3 == referenceCount);
                GridReferences = r.ReadTArray <Reference>(referenceSize, referenceSize >> 3);
            }
Пример #5
0
        public static void ReadNonfixed(BinaryFileReader r, Header header, RecordGroup group)
        {
            var world = int.Parse(header.Label);

            // header
            r.Skip(4 * 5);
            var width  = r.ReadUInt32();
            var height = r.ReadUInt32();

            r.Skip(4);
            var indexSize = (int)(width * height);
            var indices   = r.ReadTArray <uint>(indexSize * 4, indexSize);

            r.Skip(4);
            // pages
            var page     = r.ReadT <Page>(28); r.Skip(4 * 7);
            var entities = new Entity[page.EntityCount];

            for (var i = 0; i < entities.Length; i++)
            {
                entities[i] = r.ReadT <Entity>(64);
            }
        }
Пример #6
0
        public Vector3Int GridId; // => new Vector3Int(INTV.CellX, INTV.CellY, 0);

        public override bool CreateField(BinaryFileReader r, GameFormat format, string type, int dataSize)
        {
            switch (type)
            {
            case "DATA": DATA = r.ReadT <IN32Field>(dataSize); return(true);

            case "VNML": VNML = new VNMLField(r, dataSize); return(true);

            case "VHGT": VHGT = new VHGTField(r, dataSize); return(true);

            case "VCLR": VCLR = new VNMLField(r, dataSize); return(true);

            case "VTEX": VTEX = new VTEXField(r, dataSize, format); return(true);

            // TES3
            case "INTV": INTV = r.ReadT <CORDField>(dataSize); return(true);

            case "WNAM": WNAM = new WNAMField(r, dataSize); return(true);

            // TES4
            case "BTXT": var btxt = r.ReadT <BTXTField>(dataSize); BTXTs[btxt.Quadrant] = btxt; return(true);

            case "ATXT":
                if (ATXTs == null)
                {
                    ATXTs = new ATXTGroup[4];
                }
                var atxt = r.ReadT <BTXTField>(dataSize); _lastATXT = ATXTs[atxt.Quadrant] = new ATXTGroup {
                    ATXT = atxt
                }; return(true);

            case "VTXT": _lastATXT.VTXTs = r.ReadTArray <VTXTField>(dataSize, dataSize >> 3); return(true);

            default: return(false);
            }
        }
Пример #7
0
        public static void ReadFixed(BinaryFileReader r, Header header, RecordGroup group)
        {
            var world     = int.Parse(header.Label);
            var head      = r.ReadT <Head>(32);
            var indexSize = (int)(head.Width * head.Height);
            // These are either 0 or a number in the form nnnn001h, where nnnn is a number that may be a page index. This may be in [x + y * width] order, but that doesn't seem to corroborate with where objects are located in the maps
            var       indices      = r.ReadTArray <uint>(indexSize * 4, indexSize);
            const int POINT_STRIDE = 32;
            var       pages        = new Page[head.PageSize / 4096];

            for (var i = 0; i < pages.Length; i++)
            {
                var page = pages[i] = new Page();
                r.Skip(4 * 0x3);
                page.BaseX = r.ReadUInt32();
                page.BaseY = r.ReadUInt32();
                r.Skip(4 * 0x13);
                page.FixedObjects = r.ReadTArray <FixedObject>(0x18 * 166, 166);
                r.Skip(0x10);
            }
            var data = new Data
            {
                Width   = head.Width,
                Height  = head.Height,
                Indices = indices,
                Pages   = pages,
            };

            group.Tag = data;

            // transform
            const int CELL_STRIDE = 64;
            var       records     = new List <Record>();

            for (var y = 0; y < data.Height; y += 2)
            {
                for (var x = 0; x < data.Width; x += 2)
                {
                    //var vhgt = new ushort[CELL_STRIDE * CELL_STRIDE];
                    //var vtex = new ushort[CELL_STRIDE * CELL_STRIDE];
                    //var vtexf = new byte[CELL_STRIDE * CELL_STRIDE];
                    //for (var sy = 0; sy < 2; sy++)
                    //    for (var sx = 0; sx < 2; sx++)
                    //    {
                    //        var index = indices[x + sx + ((y + sy) * data.Width)];
                    //        if (index >= chunks.Length)
                    //            continue;
                    //        var chunk = chunks[index];
                    //        var offset = (sx * POINT_STRIDE) + (sy * POINT_STRIDE * CELL_STRIDE);
                    //        for (var i = 0; i < POINT_STRIDE; i++)
                    //        {
                    //            Buffer.BlockCopy(chunk.VHGT, i * POINT_STRIDE * 2, vhgt, offset + (i * CELL_STRIDE * 2), POINT_STRIDE * 2);
                    //            Buffer.BlockCopy(chunk.VTEX, i * POINT_STRIDE * 2, vtex, offset + (i * CELL_STRIDE * 2), POINT_STRIDE * 2);
                    //            Buffer.BlockCopy(chunk.VTEXF, i * POINT_STRIDE, vtexf, offset + (i * CELL_STRIDE), POINT_STRIDE);
                    //        }
                    //    }
                    records.Add(new CELLRecord
                    {
                        GridId = new Vector3Int(x / 2, y / 2, world),
                    });
                }
            }

            // insert
            group.CELLsById = records.ToDictionary(x => ((CELLRecord)x).GridId, x => (CELLRecord)x);
            group.Records.AddRange(records);
        }
Пример #8
0
            public Byte3[] Vertexs; // XYZ 8 bit floats

            public VNMLField(BinaryFileReader r, int dataSize)
            {
                Vertexs = r.ReadTArray <Byte3>(dataSize, dataSize / 3);
                //Vertexs = new Vector3Int8[dataSize / 3];
                //for (var i = 0; i < Vertexs.Length; i++) Vertexs[i] = new Vector3Int8 { X = r.ReadByte(), Y = r.ReadByte(), Z = r.ReadByte() };
            }
Пример #9
0
        public static void ReadTerrain(BinaryFileReader r, Header header, RecordGroup group)
        {
            var world = int.Parse(header.Label);
            var data  = new Data
            {
                Width         = r.ReadUInt32(),
                Height        = r.ReadUInt32(),
                Name          = r.ReadASCIIString(0x80, ASCIIFormat.ZeroTerminated),
                WaterLevel    = r.ReadUInt32(),
                WaveAmplitude = r.ReadUInt32(),
                Flags         = r.ReadUInt32(),
            };
            var       chunkCount   = (int)r.ReadUInt32();
            var       widthHeight  = (int)(data.Width * data.Height);
            var       indices      = data.Indices = r.ReadTArray <ushort>(widthHeight << 1, widthHeight);
            var       chunks       = data.Chunks = new Chunk[chunkCount];
            const int POINT_STRIDE = 16;

            for (var i = 0; i < chunks.Length; i++)
            {
                var points = r.ReadTArray <uint>(POINT_STRIDE * POINT_STRIDE * 4, POINT_STRIDE * POINT_STRIDE);
                chunks[i] = new Chunk
                {
                    VHGT  = points.Select(x => (ushort)(x & 0xFFF)).ToArray(),
                    VTEXF = points.Select(x => (byte)((x >> 16) & 0x1F)).ToArray(),
                    VTEX  = points.Select(x => (ushort)((x >> 22) & 0x3FF)).ToArray(), //: sky, >> 21?
                };
            }
            group.Tag = data;

            // transform
            //const int LAND_STRIDE = 64;
            //var records = new List<Record>();
            //var VHGTs = new Dictionary<int, ushort[]>();
            //for (var i = 0; i < POINT_STRIDE; i++)
            //    VHGTs.Add(i, Enumerable.Repeat((ushort)(i * 10), POINT_STRIDE * POINT_STRIDE).ToArray());
            //for (var y = 0; y < data.Height; y += 4)
            //    for (var x = 0; x < data.Width; x += 4)
            //    {
            //        var vhgt = new ushort[LAND_STRIDE * LAND_STRIDE];
            //        var vtex = new ushort[LAND_STRIDE * LAND_STRIDE];
            //        var vtexf = new byte[LAND_STRIDE * LAND_STRIDE];
            //        for (var sy = 0; sy < 4; sy++)
            //            for (var sx = 0; sx < 4; sx++)
            //            {
            //                var offset = ((sx * POINT_STRIDE) + (sy * POINT_STRIDE * LAND_STRIDE)) << 1;
            //                for (var i = 0; i < POINT_STRIDE; i++)
            //                {
            //                    Buffer.BlockCopy(VHGTs[i], i * POINT_STRIDE << 1, vhgt, offset + (i * LAND_STRIDE << 1), POINT_STRIDE << 1);
            //                }
            //            }
            //        records.Add(new LANDRecord
            //        {
            //            VHGT = vhgt,
            //            VTEX = vtex,
            //            VTEXF = vtexf,
            //            GridId = new Vector3Int(x / 4, y / 4, world),
            //        });
            //    }

            // transform
            const int LAND_STRIDE = 64;
            var       records     = new List <Record>();

            for (var y = 0; y < data.Height; y += 4)
            {
                for (var x = 0; x < data.Width; x += 4)
                {
                    var vhgt  = new ushort[LAND_STRIDE * LAND_STRIDE];
                    var vtex  = new ushort[LAND_STRIDE * LAND_STRIDE];
                    var vtexf = new byte[LAND_STRIDE * LAND_STRIDE];
                    for (var sy = 0; sy < 4; sy++)
                    {
                        for (var sx = 0; sx < 4; sx++)
                        {
                            var index = indices[x + sx + ((y + sy) * data.Width)];
                            if (index >= chunks.Length)
                            {
                                continue;
                            }
                            var chunk  = chunks[index];
                            var offset = ((sx * POINT_STRIDE) + (sy * POINT_STRIDE * LAND_STRIDE)) << 1;
                            for (var i = 0; i < POINT_STRIDE; i++)
                            {
                                Buffer.BlockCopy(chunk.VHGT, i * POINT_STRIDE << 1, vhgt, offset + (i * LAND_STRIDE << 1), POINT_STRIDE << 1);
                                Buffer.BlockCopy(chunk.VTEX, i * POINT_STRIDE << 1, vtex, offset + (i * LAND_STRIDE << 1), POINT_STRIDE << 1);
                                //Buffer.BlockCopy(chunk.VTEXF, i * POINT_STRIDE, vtexf, offset + (i * LAND_STRIDE), POINT_STRIDE);
                            }
                        }
                    }
                    records.Add(new LANDRecord
                    {
                        VHGT   = vhgt,
                        VTEX   = vtex,
                        VTEXF  = vtexf,
                        GridId = new Vector3Int(x / 4, y / 4, world),
                    });
                }
            }

            // insert
            group.LANDsById = records.ToDictionary(x => ((LANDRecord)x).GridId, x => (LANDRecord)x);
            group.Records.AddRange(records);
        }