Ejemplo n.º 1
0
        public Mapd(SegmentStream stream)
        {
            // This is damn ugly, but it seems MAPD uses offsets from lvl start.
            var basePosition = ((SegmentStream)stream.BaseStream).BaseStream.Position - 8;

            var test = stream.ReadInt32();

            stream.Position += test * 4;
            var generation = stream.ReadInt32() == 256 ? Generation.Gen1 : Generation.Gen2;

            stream.Position -= (test + 2) * 4;

            if (generation == Generation.Gen2)
            {
                stream.ReadInt32(); // Unk
            }
            var layerOffsets = new int[stream.ReadInt32()];

            Layers = new MapdLayer[layerOffsets.Length];

            for (var i = 0; i < layerOffsets.Length; i++)
            {
                layerOffsets[i] = stream.ReadInt32();
            }

            var palette = new byte[stream.ReadInt32() * 4];

            if (generation == Generation.Gen2)
            {
                for (var i = 0; i < palette.Length;)
                {
                    var color16 = stream.ReadUInt16(); // aRRRRRGGGGGBBBBB
                    palette[i++] = (byte)(((color16 & 0x7c00) >> 7) & 0xff);
                    palette[i++] = (byte)(((color16 & 0x03e0) >> 2) & 0xff);
                    palette[i++] = (byte)(((color16 & 0x001f) << 3) & 0xff);
                    palette[i++] = 0xff;
                }
            }
            else
            {
                stream.Read(palette);

                for (var i = 0; i < palette.Length / 4; i++)
                {
                    palette[i * 4 + 3] = 0xff;
                }
            }

            for (var i = 0; i < Layers.Length; i++)
            {
                stream.Position = layerOffsets[i] - basePosition;

                var type = new string(stream.ReadASCII(4).Reverse().ToArray());

                if (type != "SCRL")
                {
                    throw new Exception("Unknown type.");
                }

                var tileWidth  = stream.ReadInt32();
                var tileHeight = stream.ReadInt32();
                var tilesX     = stream.ReadInt32();
                var tilesY     = stream.ReadInt32();

                if (generation == Generation.Gen2)
                {
                    stream.ReadInt32(); // Unk
                    stream.ReadInt32(); // Unk
                    stream.ReadInt32(); // Unk
                }

                var tilePixels = new Dictionary <int, byte[]>();
                var tiles      = new List <int>();

                for (var y = 0; y < tilesY; y++)
                {
                    for (var x = 0; x < tilesX; x++)
                    {
                        var tile = stream.ReadInt32();

                        if (generation == Generation.Gen2)
                        {
                            tile -= tile % 4;
                        }

                        tiles.Add(tile);

                        if (tile != 0 && !tilePixels.ContainsKey(tile))
                        {
                            tilePixels.Add(tile, new byte[tileWidth * tileHeight * 4]);
                        }
                    }
                }

                foreach (var(offset, pixels) in tilePixels)
                {
                    stream.Position = offset - basePosition;

                    if (generation == Generation.Gen1)
                    {
                        stream.ReadInt32(); // Unk
                    }
                    for (var y = 0; y < tileHeight; y++)
                    {
                        for (var x = 0; x < tileWidth; x++)
                        {
                            var index = stream.ReadByte();

                            if (index == 0 && i != 0)
                            {
                                continue;
                            }

                            Array.Copy(palette, index * 4, pixels, (y * tileWidth + x) * 4, 4);
                        }
                    }
                }

                var layer = new MapdLayer(tilesX * tileWidth, tilesY * tileHeight);
                Layers[i] = layer;

                for (var y = 0; y < tilesY; y++)
                {
                    for (var x = 0; x < tilesX; x++)
                    {
                        var tile = tiles[y * tilesX + x];

                        if (tile == 0)
                        {
                            continue;
                        }

                        var pixels = tilePixels[tile];
                        var offset = (y * tileHeight * tilesX + x) * tileWidth;

                        for (var row = 0; row < tileHeight; row++)
                        {
                            Array.Copy(pixels, row * tileWidth * 4, layer.Pixels, (offset + row * layer.Width) * 4, tileWidth * 4);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public uint[,] ApplyFrame(uint[,] oldFrame, ref uint[] palette, ref string textData)
        {
            var width  = oldFrame.GetLength(1);
            var height = oldFrame.GetLength(0);

            var newFrame = new uint[height, width];

            // We use Buffer.BlockCopy as Array.Copy does not properly handle 2d array!
            var shift = (globalMotion.X + globalMotion.Y * width) * 4;

            if (shift >= 0)
            {
                Buffer.BlockCopy(oldFrame, shift, newFrame, 0, oldFrame.Length * 4 - shift);
            }
            else
            {
                Buffer.BlockCopy(oldFrame, 0, newFrame, -shift, oldFrame.Length * 4 + shift);
            }

            int[] patterns =
            {
                0x0660, 0xFF00, 0xCCCC, 0xF000, 0x8888, 0x000F, 0x1111, 0xFEC8,
                0x8CEF, 0x137F, 0xF731, 0xC800, 0x008C, 0x0013, 0x3100, 0xCC00,
                0x00CC, 0x0033, 0x3300, 0x0FF0, 0x6666, 0x00F0, 0x0F00, 0x2222,
                0x4444, 0xF600, 0x8CC8, 0x006F, 0x1331, 0x318C, 0xC813, 0x33CC,
                0x6600, 0x0CC0, 0x0066, 0x0330, 0xF900, 0xC88C, 0x009F, 0x3113,
                0x6000, 0x0880, 0x0006, 0x0110, 0xCC88, 0xFC00, 0x00CF, 0x88CC,
                0x003F, 0x1133, 0x3311, 0xF300, 0x6FF6, 0x0603, 0x08C6, 0x8C63,
                0xC631, 0x6310, 0xC060, 0x0136, 0x136C, 0x36C8, 0x6C80, 0x324C
            };

            if (colors != null)
            {
                colors.Position = 0;

                var firstIndex = colors.ReadUInt8();
                var numColors  = (colors.ReadUInt8() - 1) & 0xff;

                for (var i = 0; i <= numColors; i++)
                {
                    palette[firstIndex + i] = (uint)((0xff << 24) | (colors.ReadUInt8() << 16) | (colors.ReadUInt8() << 8) | (colors.ReadUInt8() << 0));
                }
            }

            video.Position = 0;

            for (var by = 0; by < height / 4; by++)
            {
                for (var bx = 0; bx < width / 4;)
                {
                    var blockTypes = video.ReadUInt8();

                    for (var i = 0; i < 4; i++, bx++)
                    {
                        var blockType = (blockTypes >> (6 - i * 2)) & 0x03;

                        switch (blockType)
                        {
                        case 0:
                        {
                            break;
                        }

                        case 1:
                        {
                            var motion = video.ReadUInt8();

                            if (motion == 0)
                            {
                                for (var y = 0; y < 4; y++)
                                {
                                    for (var x = 0; x < 4; x++)
                                    {
                                        newFrame[by * 4 + y, bx * 4 + x] = palette[video.ReadByte()];
                                    }
                                }
                            }
                            else
                            {
                                var motionX = ((motion & 0xf) ^ 8) - 8;
                                var motionY = ((motion >> 4) ^ 8) - 8;

                                for (var y = 0; y < 4; y++)
                                {
                                    for (var x = 0; x < 4; x++)
                                    {
                                        newFrame[by * 4 + y, bx * 4 + x] = oldFrame[by * 4 + y + globalMotion.Y + motionY, bx * 4 + x + globalMotion.X + motionX];
                                    }
                                }
                            }

                            break;
                        }

                        case 2:
                        {
                            var color = palette[video.ReadUInt8()];

                            for (var y = 0; y < 4; y++)
                            {
                                for (var x = 0; x < 4; x++)
                                {
                                    newFrame[by * 4 + y, bx * 4 + x] = color;
                                }
                            }

                            break;
                        }

                        case 3:
                        {
                            var patternData = video.ReadUInt8();
                            var patternType = patternData >> 6;
                            var pattern     = patterns[patternData & 0x3f];

                            switch (patternType)
                            {
                            case 0:
                            {
                                var pixel0 = palette[video.ReadUInt8()];
                                var pixel1 = palette[video.ReadUInt8()];

                                for (var y = 0; y < 4; y++)
                                {
                                    for (var x = 0; x < 4; x++)
                                    {
                                        newFrame[by * 4 + y, bx * 4 + x] = ((pattern >> (y * 4 + x)) & 1) == 0 ? pixel0 : pixel1;
                                    }
                                }

                                break;
                            }

                            case 1:
                            {
                                var pixel = palette[video.ReadUInt8()];

                                for (var y = 0; y < 4; y++)
                                {
                                    for (var x = 0; x < 4; x++)
                                    {
                                        if (((pattern >> (y * 4 + x)) & 1) == 1)
                                        {
                                            newFrame[by * 4 + y, bx * 4 + x] = pixel;
                                        }
                                    }
                                }

                                break;
                            }

                            case 2:
                            {
                                var pixel = palette[video.ReadUInt8()];

                                for (var y = 0; y < 4; y++)
                                {
                                    for (var x = 0; x < 4; x++)
                                    {
                                        if (((pattern >> (y * 4 + x)) & 1) == 0)
                                        {
                                            newFrame[by * 4 + y, bx * 4 + x] = pixel;
                                        }
                                    }
                                }

                                break;
                            }
                            }

                            break;
                        }
                        }
                    }
                }
            }

            if (Text != null)
            {
                textData = Text;
            }

            return(newFrame);
        }