Example #1
0
            public R8Frame(Stream s)
            {
                // Scan forward until we find some data
                var type = s.ReadUInt8();
                while (type == 0)
                    type = s.ReadUInt8();

                var width = s.ReadInt32();
                var height = s.ReadInt32();
                var x = s.ReadInt32();
                var y = s.ReadInt32();

                Size = new Size(width, height);
                Offset = new int2(width / 2 - x, height / 2 - y);

                /*var imageOffset = */
                s.ReadInt32();
                var paletteOffset = s.ReadInt32();
                var bpp = s.ReadUInt8();
                if (bpp != 8)
                    throw new InvalidDataException("Error: {0} bits per pixel are not supported.".F(bpp));

                var frameHeight = s.ReadUInt8();
                var frameWidth = s.ReadUInt8();
                FrameSize = new Size(frameWidth, frameHeight);

                // Skip alignment byte
                s.ReadUInt8();

                Data = s.ReadBytes(width * height);

                // Ignore palette
                if (type == 1 && paletteOffset != 0)
                    s.Seek(520, SeekOrigin.Current);
            }
        public Container(Stream stream)
        {
            UInt16 stringLength = stream.ReadUInt16();
            Name = stream.ReadAsciiString(stringLength);
            ContainerType = stream.ReadUInt8();
            Flags = (ContainerFlags)stream.ReadUInt16();
            PrimitiveCount = stream.ReadUInt16();
            PackfileBaseOffset = stream.ReadUInt32();
            CompressionType = stream.ReadUInt8();
            stringLength = stream.ReadUInt16();
            StubContainerParentName = stream.ReadAsciiString(stringLength);
            Int32 auxDataSize = stream.ReadInt32();
            AuxData = new byte[auxDataSize];
            stream.Read(AuxData, 0, auxDataSize);
            TotalCompressedPackfileReadSize = stream.ReadInt32();

            Primitives = new List<Primitive>();
            PrimitiveSizes = new List<WriteTimeSizes>();

            for (UInt16 i = 0; i < PrimitiveCount; i++)
            {
                var sizes = stream.ReadStruct<WriteTimeSizes>();
                PrimitiveSizes.Add(sizes);
            }

            for (UInt16 i = 0; i < PrimitiveCount; i++)
            {
                Primitive primitive = new Primitive(stream);
                Primitives.Add(primitive);
            }
        }
Example #3
0
        public XccGlobalDatabase(Stream stream)
        {
            s = stream;

            var entries = new List<string>();
            while (s.Peek() > -1)
            {
                var count = s.ReadInt32();
                for (var i = 0; i < count; i++)
                {
                    var chars = new List<char>();
                    byte c;

                    // Read filename
                    while ((c = s.ReadUInt8()) != 0)
                        chars.Add((char)c);
                    entries.Add(new string(chars.ToArray()));

                    // Skip comment
                    while ((c = s.ReadUInt8()) != 0) { }
                }
            }

            Entries = entries.ToArray();
        }
Example #4
0
			public ShpD2Frame(Stream s)
			{
				var flags = (FormatFlags)s.ReadUInt16();
				s.Position += 1;
				var width = s.ReadUInt16();
				var height = s.ReadUInt8();
				Size = new Size(width, height);

				// Subtract header size
				var dataLeft = s.ReadUInt16() - 10;
				var dataSize = s.ReadUInt16();

				byte[] table;
				if ((flags & FormatFlags.PaletteTable) != 0)
				{
					var n = (flags & FormatFlags.VariableLengthTable) != 0 ? s.ReadUInt8() : (byte)16;
					table = new byte[n];
					for (var i = 0; i < n; i++)
						table[i] = s.ReadUInt8();

					dataLeft -= n;
				}
				else
				{
					table = new byte[256];
					for (var i = 0; i < 256; i++)
						table[i] = (byte)i;
					table[1] = 0x7f;
					table[2] = 0x7e;
					table[3] = 0x7d;
					table[4] = 0x7c;
				}

				Data = new byte[width * height];

				// Decode image data
				var compressed = s.ReadBytes(dataLeft);
				if ((flags & FormatFlags.SkipFormat80) == 0)
				{
					var temp = new byte[dataSize];
					Format80.DecodeInto(compressed, temp);
					compressed = temp;
				}

				Format2.DecodeInto(compressed, Data, 0);

				// Lookup values in lookup table
				for (var j = 0; j < Data.Length; j++)
					Data[j] = table[Data[j]];
			}
Example #5
0
		static bool IsShpTD(Stream s)
		{
			var start = s.Position;

			// First word is the image count
			var imageCount = s.ReadUInt16();
			if (imageCount == 0)
			{
				s.Position = start;
				return false;
			}

			// Last offset should point to the end of file
			var finalOffset = start + 14 + 8 * imageCount;
			if (finalOffset > s.Length)
			{
				s.Position = start;
				return false;
			}

			s.Position = finalOffset;
			var eof = s.ReadUInt32();
			if (eof != s.Length)
			{
				s.Position = start;
				return false;
			}

			// Check the format flag on the first frame
			s.Position = start + 17;
			var b = s.ReadUInt8();

			s.Position = start;
			return b == 0x20 || b == 0x40 || b == 0x80;
		}
Example #6
0
		bool IsR8(Stream s)
		{
			var start = s.Position;

			// First byte is nonzero
			if (s.ReadUInt8() == 0)
			{
				s.Position = start;
				return false;
			}

			// Check the format of the first frame
			s.Position = start + 25;
			var d = s.ReadUInt8();

			s.Position = start;
			return d == 8;
		}
        public Stream2File(Stream stream)
        {
            Header = stream.ReadStruct<ContainerFileHeader>();

            uint allocatorTypeCount = stream.ReadUInt32();
            for (uint i = 0; i < allocatorTypeCount; i++)
            {
                UInt16 stringLength = stream.ReadUInt16();
                string name = stream.ReadAsciiString(stringLength);
                byte id = stream.ReadUInt8();
                AllocatorTypes.Add(id, name);
            }

            uint primitiveTypeCount = stream.ReadUInt32();
            for (uint i = 0; i < primitiveTypeCount; i++)
            {
                UInt16 stringLength = stream.ReadUInt16();
                string name = stream.ReadAsciiString(stringLength);
                byte id = stream.ReadUInt8();
                PrimitiveTypes.Add(id, name);
            }

            uint containerTypeCount = stream.ReadUInt32();
            for (uint i = 0; i < containerTypeCount; i++)
            {
                UInt16 stringLength = stream.ReadUInt16();
                string name = stream.ReadAsciiString(stringLength);
                byte id = stream.ReadUInt8();
                ContainerTypes.Add(id, name);
            }

            for (uint i = 0; i < Header.NumContainers; i++)
            {
                Container container = new Container(stream);
                Containers.Add(container);
            }
        }
Example #8
0
        public BinaryDataHeader(Stream s, int2 expectedSize)
        {
            Format = s.ReadUInt8();
            var width = s.ReadUInt16();
            var height = s.ReadUInt16();
            if (width != expectedSize.X || height != expectedSize.Y)
                throw new InvalidDataException("Invalid tile data");

            if (Format == 1)
            {
                TilesOffset = 5;
                HeightsOffset = 0;
                ResourcesOffset = (uint)(3 * width * height + 5);
            }
            else if (Format == 2)
            {
                TilesOffset = s.ReadUInt32();
                HeightsOffset = s.ReadUInt32();
                ResourcesOffset = s.ReadUInt32();
            }
            else
                throw new InvalidDataException("Unknown binary map format '{0}'".F(Format));
        }
Example #9
0
        bool IsShpTS(Stream s)
        {
            var start = s.Position;

            // First word is zero
            if (s.ReadUInt16() != 0)
            {
                s.Position = start;
                return false;
            }

            // Sanity Check the image count
            s.Position += 4;
            var imageCount = s.ReadUInt16();
            if (s.Position + 24 * imageCount > s.Length)
            {
                s.Position = start;
                return false;
            }

            // Check the size and format flag
            // Some files define bogus frames, so loop until we find a valid one
            s.Position += 4;
            ushort w, h, f = 0;
            byte type;
            do
            {
                w = s.ReadUInt16();
                h = s.ReadUInt16();
                type = s.ReadUInt8();
            }
            while (w == 0 && h == 0 && f++ < imageCount);

            s.Position = start;
            return type < 4;
        }
Example #10
0
        // VQA Frame
        public void DecodeVQFR(Stream s)
        {
            while (true)
            {
                // Chunks are aligned on even bytes; may be padded with a single null
                if (s.Peek() == 0) s.ReadByte();
                var type = s.ReadASCII(4);
                var subchunkLength = (int)int2.Swap(s.ReadUInt32());

                switch(type)
                {
                    // Full frame-modifier
                    case "CBFZ":
                        Format80.DecodeInto(s.ReadBytes(subchunkLength), cbf);
                    break;
                    case "CBF0":
                        cbf = s.ReadBytes(subchunkLength);
                    break;

                    // frame-modifier chunk
                    case "CBP0":
                    case "CBPZ":
                        // Partial buffer is full; dump and recreate
                        if (cbChunk == cbParts)
                        {
                            if (type == "CBP0")
                                cbf = (byte[])cbp.Clone();
                            else
                                Format80.DecodeInto(cbp, cbf);

                            cbOffset = cbChunk = 0;
                        }

                        var bytes = s.ReadBytes(subchunkLength);
                        bytes.CopyTo(cbp,cbOffset);
                        cbOffset += subchunkLength;
                        cbChunk++;
                    break;

                    // Palette
                    case "CPL0":
                        for (var i = 0; i < numColors; i++)
                        {
                            var r = (byte)(s.ReadUInt8() << 2);
                            var g = (byte)(s.ReadUInt8() << 2);
                            var b = (byte)(s.ReadUInt8() << 2);
                            palette[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
                        }
                    break;

                    // Frame data
                    case "VPTZ":
                        Format80.DecodeInto(s.ReadBytes(subchunkLength), origData);
                        // This is the last subchunk
                        return;
                    default:
                        throw new InvalidDataException("Unknown sub-chunk {0}".F(type));
                }
            }
        }
Example #11
0
		// VQA Frame
		public void DecodeVQFR(Stream s, string parentType = "VQFR")
		{
			while (true)
			{
				// Chunks are aligned on even bytes; may be padded with a single null
				if (s.Peek() == 0) s.ReadByte();
				var type = s.ReadASCII(4);
				var subchunkLength = (int)int2.Swap(s.ReadUInt32());

				switch (type)
				{
					// Full frame-modifier
					case "CBFZ":
						var decodeMode = s.Peek() == 0;
						s.ReadBytes(fileBuffer, 0, subchunkLength);
						Array.Clear(cbf, 0, cbf.Length);
						Array.Clear(cbfBuffer, 0, cbfBuffer.Length);
						var decodeCount = 0;
						decodeCount = Format80.DecodeInto(fileBuffer, cbfBuffer, decodeMode ? 1 : 0, decodeMode);
						if ((videoFlags & 0x10) == 16)
						{
							var p = 0;
							for (var i = 0; i < decodeCount; i += 2)
							{
								var packed = cbfBuffer[i + 1] << 8 | cbfBuffer[i];
								/* 15      bit      0
								   0rrrrrgg gggbbbbb
								   HI byte  LO byte*/
								cbf[p++] = (byte)((packed & 0x7C00) >> 7);
								cbf[p++] = (byte)((packed & 0x3E0) >> 2);
								cbf[p++] = (byte)((packed & 0x1f) << 3);
							}
						}
						else
						{
							cbf = cbfBuffer;
						}

						if (parentType == "VQFL")
							return;
						break;
					case "CBF0":
						cbf = s.ReadBytes(subchunkLength);
						break;

					// frame-modifier chunk
					case "CBP0":
					case "CBPZ":
						// Partial buffer is full; dump and recreate
						if (currentChunkBuffer == chunkBufferParts)
						{
							if (type == "CBP0")
								cbf = (byte[])cbp.Clone();
							else
								Format80.DecodeInto(cbp, cbf);

							chunkBufferOffset = currentChunkBuffer = 0;
						}

						var bytes = s.ReadBytes(subchunkLength);
						bytes.CopyTo(cbp, chunkBufferOffset);
						chunkBufferOffset += subchunkLength;
						currentChunkBuffer++;
						break;

					// Palette
					case "CPL0":
						for (var i = 0; i < numColors; i++)
						{
							var r = (byte)(s.ReadUInt8() << 2);
							var g = (byte)(s.ReadUInt8() << 2);
							var b = (byte)(s.ReadUInt8() << 2);
							palette[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
						}

						break;

					// Frame data
					case "VPTZ":
						Format80.DecodeInto(s.ReadBytes(subchunkLength), origData);

						// This is the last subchunk
						return;
					case "VPRZ":
						Array.Clear(origData, 0, origData.Length);
						s.ReadBytes(fileBuffer, 0, subchunkLength);
						if (fileBuffer[0] != 0)
							vtprSize = Format80.DecodeInto(fileBuffer, origData);
						else
							Format80.DecodeInto(fileBuffer, origData, 1, true);
						return;
					case "VPTR":
						Array.Clear(origData, 0, origData.Length);
						s.ReadBytes(origData, 0, subchunkLength);
						vtprSize = subchunkLength;
						return;
					default:
						throw new InvalidDataException("Unknown sub-chunk {0}".F(type));
				}
			}
		}
Example #12
0
		public VqaReader(Stream stream)
		{
			this.stream = stream;

			// Decode FORM chunk
			if (stream.ReadASCII(4) != "FORM")
				throw new InvalidDataException("Invalid vqa (invalid FORM section)");
			/*var length = */stream.ReadUInt32();

			if (stream.ReadASCII(8) != "WVQAVQHD")
				throw new InvalidDataException("Invalid vqa (not WVQAVQHD)");
			/*var length2 = */stream.ReadUInt32();

			/*var version = */stream.ReadUInt16();
			videoFlags = stream.ReadUInt16();
			Frames = stream.ReadUInt16();
			Width = stream.ReadUInt16();
			Height = stream.ReadUInt16();

			blockWidth = stream.ReadUInt8();
			blockHeight = stream.ReadUInt8();
			Framerate = stream.ReadUInt8();
			chunkBufferParts = stream.ReadUInt8();
			blocks = new int2(Width / blockWidth, Height / blockHeight);

			numColors = stream.ReadUInt16();
			/*var maxBlocks = */stream.ReadUInt16();
			/*var unknown1 = */stream.ReadUInt16();
			/*var unknown2 = */stream.ReadUInt32();

			// Audio
			sampleRate = stream.ReadUInt16();
			audioChannels = stream.ReadByte();
			sampleBits = stream.ReadByte();

			/*var unknown3 =*/stream.ReadUInt32();
			/*var unknown4 =*/stream.ReadUInt16();
			/*maxCbfzSize =*/stream.ReadUInt32(); // Unreliable

			/*var unknown5 =*/stream.ReadUInt32();

			var frameSize = Exts.NextPowerOf2(Math.Max(Width, Height));

			if (IsHqVqa)
			{
				cbfBuffer = new byte[maxCbfzSize];
				cbf = new byte[maxCbfzSize * 3];
				origData = new byte[maxCbfzSize];
			}
			else
			{
				cbfBuffer = new byte[Width * Height];
				cbf = new byte[Width * Height];
				cbp = new byte[Width * Height];
				origData = new byte[2 * blocks.X * blocks.Y];
			}

			palette = new uint[numColors];
			frameData = new uint[frameSize, frameSize];
			var type = stream.ReadASCII(4);
			while (type != "FINF")
			{
				// Sub type is a file tag
				if (type[3] == 'F')
				{
					var jmp = int2.Swap(stream.ReadUInt32());
					stream.Seek(jmp, SeekOrigin.Current);
					type = stream.ReadASCII(4);
				}
				else
					throw new NotSupportedException("Vqa uses unknown Subtype: {0}".F(type));
			}

			/*var length = */stream.ReadUInt16();
			/*var unknown4 = */stream.ReadUInt16();

			// Frame offsets
			offsets = new uint[Frames];
			for (var i = 0; i < Frames; i++)
			{
				offsets[i] = stream.ReadUInt32();
				if (offsets[i] > 0x40000000)
					offsets[i] -= 0x40000000;
				offsets[i] <<= 1;
			}

			CollectAudioData();

			Reset();
		}
Example #13
0
        public TmpTSTile(Stream s, Size size)
        {
            Size = size;

            // Ignore tile header for now
            s.Position += 52;

            Data = new byte[size.Width * size.Height];

            // Unpack tile data
            var width = 4;
            for (var i = 0; i < size.Height; i++)
            {
                var start = i * size.Width + (size.Width - width) / 2;
                for (var j = 0; j < width; j++)
                    Data[start + j] = s.ReadUInt8();

                width += (i < size.Height / 2 - 1? 1 : -1) * 4;
            }

            // Ignore Z-data for now
            // Ignore extra data for now
        }
Example #14
0
            public ShpTSFrame(Stream s, Size frameSize)
            {
                var x = s.ReadUInt16();
                var y = s.ReadUInt16();
                var width = s.ReadUInt16();
                var height = s.ReadUInt16();

                // Pad the dimensions to an even number to avoid issues with half-integer offsets
                var dataWidth = width;
                var dataHeight = height;
                if (dataWidth % 2 == 1)
                    dataWidth += 1;

                if (dataHeight % 2 == 1)
                    dataHeight += 1;

                Offset = new int2(x + (dataWidth - frameSize.Width) / 2, y + (dataHeight - frameSize.Height) / 2);
                Size = new Size(dataWidth, dataHeight);
                FrameSize = frameSize;

                Format = s.ReadUInt8();
                s.Position += 11;
                FileOffset = s.ReadUInt32();

                if (FileOffset == 0)
                    return;

                // Parse the frame data as we go (but remember to jump back to the header before returning!)
                var start = s.Position;
                s.Position = FileOffset;

                Data = new byte[dataWidth * dataHeight];

                if (Format == 3)
                {
                    // Format 3 provides RLE-zero compressed scanlines
                    for (var j = 0; j < height; j++)
                    {
                        var length = s.ReadUInt16() - 2;
                        Format2.DecodeInto(s.ReadBytes(length), Data, dataWidth * j);
                    }
                }
                else
                {
                    // Format 2 provides uncompressed length-prefixed scanlines
                    // Formats 1 and 0 provide an uncompressed full-width row
                    var length = Format == 2 ? s.ReadUInt16() - 2 : width;
                    for (var j = 0; j < height; j++)
                        s.ReadBytes(Data, dataWidth * j, length);
                }

                s.Position = start;
            }
            public FileDescriptor(Stream stream, uint index, long tableOffset)
            {
                Index = index;
                Flags = (CABFlags)stream.ReadUInt16();
                ExpandedSize = stream.ReadUInt32();
                stream.Position += 4;
                CompressedSize = stream.ReadUInt32();

                stream.Position += 4;
                DataOffset = stream.ReadUInt32();
                stream.Position += 4;
                MD5 = stream.ReadBytes(16);

                stream.Position += 16;
                NameOffset = stream.ReadUInt32();
                DirectoryIndex = stream.ReadUInt16();
                stream.Position += 12;
                LinkToPrevious = stream.ReadUInt32();
                LinkToNext = stream.ReadUInt32();

                LinkFlags = (LinkFlags)stream.ReadUInt8();
                Volume = stream.ReadUInt16();

                var pos = stream.Position;
                stream.Position = tableOffset + NameOffset;
                Filename = stream.ReadASCIIZ();
                stream.Position = pos;
            }
Example #16
0
        public static byte[] LoadSound(Stream s)
        {
            /*var sampleRate =*/ s.ReadUInt16();
            var dataSize = s.ReadInt32();
            var outputSize = s.ReadInt32();
            /*var flags = (SoundFlags)*/ s.ReadByte();
            /*var format = (SoundFormat)*/ s.ReadByte();

            var output = new byte[outputSize];
            var offset = 0;
            var index = 0;
            var currentSample = 0;

            while (dataSize > 0)
            {
                var chunk = Chunk.Read(s);
                for (int n = 0; n < chunk.CompressedSize; n++)
                {
                    var b = s.ReadUInt8();

                    var t = DecodeSample(b, ref index, ref currentSample);
                    output[offset++] = (byte)t;
                    output[offset++] = (byte)(t >> 8);

                    if (offset < outputSize)
                    {
                        /* possible that only half of the final byte is used! */
                        t = DecodeSample((byte)(b >> 4), ref index, ref currentSample);
                        output[offset++] = (byte)t;
                        output[offset++] = (byte)(t >> 8);
                    }
                }

                dataSize -= 8 + chunk.CompressedSize;
            }

            return output;
        }
Example #17
0
        public static bool LoadSound(Stream s, out byte[] rawData, out int sampleRate)
        {
            rawData = null;

            sampleRate = s.ReadUInt16();
            var dataSize = s.ReadInt32();
            var outputSize = s.ReadInt32();

            var readFlag = s.ReadByte();
            if (!Enum.IsDefined(typeof(SoundFlags), readFlag))
                return false;

            var readFormat = s.ReadByte();
            if (!Enum.IsDefined(typeof(SoundFormat), readFormat))
                return false;

            var output = new byte[outputSize];
            var offset = 0;
            var index = 0;
            var currentSample = 0;

            while (dataSize > 0)
            {
                var chunk = Chunk.Read(s);
                for (var n = 0; n < chunk.CompressedSize; n++)
                {
                    var b = s.ReadUInt8();

                    var t = DecodeSample(b, ref index, ref currentSample);
                    output[offset++] = (byte)t;
                    output[offset++] = (byte)(t >> 8);

                    if (offset < outputSize)
                    {
                        /* possible that only half of the final byte is used! */
                        t = DecodeSample((byte)(b >> 4), ref index, ref currentSample);
                        output[offset++] = (byte)t;
                        output[offset++] = (byte)(t >> 8);
                    }
                }

                dataSize -= 8 + chunk.CompressedSize;
            }

            rawData = output;
            return true;
        }
Example #18
0
        void UnpackCncTileData(Stream ms)
        {
            for (int i = 0; i < mapSize; i++)
                for (int j = 0; j < mapSize; j++)
                    map.MapTiles.Value[i, j] = new TileReference<ushort, byte>();

            for (int j = 0; j < mapSize; j++)
            {
                for (int i = 0; i < mapSize; i++)
                {
                    map.MapTiles.Value[i, j].Type = ms.ReadUInt8();
                    map.MapTiles.Value[i, j].Index = ms.ReadUInt8();
                }
            }
        }
Example #19
0
        public VqaReader(Stream stream)
        {
            this.stream = stream;

            // Decode FORM chunk
            if (stream.ReadASCII(4) != "FORM")
                throw new InvalidDataException("Invalid vqa (invalid FORM section)");
            /*var length = */ stream.ReadUInt32();

            if (stream.ReadASCII(8) != "WVQAVQHD")
                throw new InvalidDataException("Invalid vqa (not WVQAVQHD)");
            /* var length = */stream.ReadUInt32();

            /*var version = */stream.ReadUInt16();
            /*var flags = */stream.ReadUInt16();
            Frames = stream.ReadUInt16();
            Width = stream.ReadUInt16();
            Height = stream.ReadUInt16();

            blockWidth = stream.ReadUInt8();
            blockHeight = stream.ReadUInt8();
            Framerate = stream.ReadUInt8();
            cbParts = stream.ReadUInt8();
            blocks = new int2(Width / blockWidth, Height / blockHeight);

            numColors = stream.ReadUInt16();
            /*var maxBlocks = */stream.ReadUInt16();
            /*var unknown1 = */stream.ReadUInt16();
            /*var unknown2 = */stream.ReadUInt32();

            // Audio
            /*var freq = */stream.ReadUInt16();
            /*var channels = */stream.ReadByte();
            /*var bits = */stream.ReadByte();
            /*var unknown3 = */stream.ReadBytes(14);

            var frameSize = Exts.NextPowerOf2(Math.Max(Width, Height));
            cbf = new byte[Width*Height];
            cbp = new byte[Width*Height];
            palette = new uint[numColors];
            origData = new byte[2*blocks.X*blocks.Y];
            frameData = new uint[frameSize, frameSize];

            var type = stream.ReadASCII(4);
            if (type != "FINF")
            {
                stream.Seek(27, SeekOrigin.Current);
                type = stream.ReadASCII(4);
            }

            /*var length = */stream.ReadUInt16();
            /*var unknown4 = */stream.ReadUInt16();

            // Frame offsets
            offsets = new UInt32[Frames];
            for (var i = 0; i < Frames; i++)
            {
                offsets[i] = stream.ReadUInt32();
                if (offsets[i] > 0x40000000)
                    offsets[i] -= 0x40000000;
                offsets[i] <<= 1;
            }

            CollectAudioData();

            Reset();
        }
Example #20
0
			public TmpTSFrame(Stream s, Size size, int u, int v)
			{
				if (s.Position != 0)
				{
					Size = size;

					// Skip unnecessary header data
					s.Position += 20;

					// Extra data is specified relative to the top-left of the template
					var extraX = s.ReadInt32() - (u - v) * size.Width / 2;
					var extraY = s.ReadInt32() - (u + v) * size.Height / 2;
					var extraWidth = s.ReadInt32();
					var extraHeight = s.ReadInt32();
					var flags = s.ReadUInt32();

					var bounds = new Rectangle(0, 0, size.Width, size.Height);
					if ((flags & 0x01) != 0)
					{
						var extraBounds = new Rectangle(extraX, extraY, extraWidth, extraHeight);
						bounds = Rectangle.Union(bounds, extraBounds);

						Offset = new float2(bounds.X + 0.5f * (bounds.Width - size.Width), bounds.Y + 0.5f * (bounds.Height - size.Height));
						Size = new Size(bounds.Width, bounds.Height);
					}

					// Skip unnecessary header data
					s.Position += 12;

					Data = new byte[bounds.Width * bounds.Height];
					DepthData = new byte[bounds.Width * bounds.Height];

					UnpackTileData(s, Data, size, bounds);
					UnpackTileData(s, DepthData, size, bounds);

					if ((flags & 0x01) == 0)
						return;

					// Load extra data (cliff faces, etc)
					for (var j = 0; j < extraHeight; j++)
					{
						var start = (j + extraY - bounds.Y) * bounds.Width + extraX - bounds.X;
						for (var i = 0; i < extraWidth; i++)
						{
							var extra = s.ReadUInt8();
							if (extra != 0)
								Data[start + i] = extra;
						}
					}

					// Extra data depth
					for (var j = 0; j < extraHeight; j++)
					{
						var start = (j + extraY - bounds.Y) * bounds.Width + extraX - bounds.X;
						for (var i = 0; i < extraWidth; i++)
						{
							var extra = s.ReadUInt8();

							// XCC source indicates that there are only 32 valid values
							if (extra < 32)
								DepthData[start + i] = extra;
						}
					}
				}
				else
					Data = new byte[0];
			}
Example #21
0
		static void UnpackTileData(Stream s, byte[] data, Size size, Rectangle frameBounds)
		{
			var width = 4;
			for (var j = 0; j < size.Height; j++)
			{
				var start = (j - frameBounds.Y) * frameBounds.Width + (size.Width - width) / 2 - frameBounds.X;
				for (var i = 0; i < width; i++)
					data[start + i] = s.ReadUInt8();

				width += (j < size.Height / 2 - 1 ? 1 : -1) * 4;
			}
		}
Example #22
0
        void ReadVoxelData(Stream s, VxlLimb l)
        {
            var baseSize = l.Size[0]*l.Size[1];
            var colStart = new int[baseSize];
            for (var i = 0; i < baseSize; i++)
                colStart[i] = s.ReadInt32();
            s.Seek(4*baseSize, SeekOrigin.Current);
            var dataStart = s.Position;

            // Count the voxels in this limb
            l.VoxelCount = 0;
            for (var i = 0; i < baseSize; i++)
            {
                // Empty column
                if (colStart[i] == -1)
                    continue;

                s.Seek(dataStart + colStart[i], SeekOrigin.Begin);
                var z = 0;
                do
                {
                    z += s.ReadUInt8();
                    var count = s.ReadUInt8();
                    z += count;
                    l.VoxelCount += count;
                    s.Seek(2*count + 1, SeekOrigin.Current);
                } while (z < l.Size[2]);
            }

            // Read the data
            l.VoxelMap = new Dictionary<byte, VxlElement>[l.Size[0],l.Size[1]];
            for (var i = 0; i < baseSize; i++)
            {
                // Empty column
                if (colStart[i] == -1)
                    continue;

                s.Seek(dataStart + colStart[i], SeekOrigin.Begin);

                byte x = (byte)(i % l.Size[0]);
                byte y = (byte)(i / l.Size[0]);
                byte z = 0;
                l.VoxelMap[x,y] = new Dictionary<byte, VxlElement>();
                do
                {
                    z += s.ReadUInt8();
                    var count = s.ReadUInt8();
                    for (var j = 0; j < count; j++)
                    {
                        var v = new VxlElement();
                        v.Color = s.ReadUInt8();
                        v.Normal = s.ReadUInt8();

                        l.VoxelMap[x,y].Add(z, v);
                        z++;
                    }
                    // Skip duplicate count
                    s.ReadUInt8();
                } while (z < l.Size[2]);
            }
        }
Example #23
0
        public FrameHeader(Stream stream, Size frameSize)
        {
            var x = stream.ReadUInt16();
            var y = stream.ReadUInt16();
            var width = stream.ReadUInt16();
            var height = stream.ReadUInt16();

            Offset = new float2(x + 0.5f * (width - frameSize.Width), y + 0.5f * (height - frameSize.Height));
            Size = new Size(width, height);
            FrameSize = frameSize;

            Format = stream.ReadUInt8();
            stream.Position += 11;
            FileOffset = stream.ReadUInt32();
        }
Example #24
0
		void UnpackCncTileData(Stream ms)
		{
			for (var j = 0; j < mapSize; j++)
			{
				for (var i = 0; i < mapSize; i++)
				{
					var type = ms.ReadUInt8();
					var index = ms.ReadUInt8();
					map.MapTiles.Value[new CPos(i, j)] = new TerrainTile(type, index);
				}
			}
		}
 void UnpackTileData(Stream ms)
 {
     for (var j = 0; j < MapSize; j++)
     {
         for (var i = 0; i < MapSize; i++)
         {
             var type = ms.ReadUInt8();
             var index = ms.ReadUInt8();
             Map.Tiles[new CPos(i, j)] = new TerrainTile(type, index);
         }
     }
 }