Exemple #1
0
        public MobdImage(SegmentStream stream, uint flags, Version version)
        {
            bool flipped;

            Width  = stream.ReadUInt32();
            Height = stream.ReadUInt32();
            Pixels = new byte[Width * Height];

            if (version == Version.KKND1)
            {
                flipped = (flags & 0x1) == 1;

                var isCompressed = stream.ReadUInt8() == 2;

                if (isCompressed)
                {
                    DecompressKknd1(stream);
                }
                else
                {
                    stream.ReadBytes(Pixels, 0, Pixels.Length);
                }
            }
            else
            {
                flipped = ((flags >> 31) & 0x1) == 1;
                var isCompressed = ((flags >> 27) & 0x1) == 1;
                var has256Colors = ((flags >> 26) & 0x1) == 1;

                if (isCompressed)
                {
                    DecompressKknd2(stream, has256Colors);
                }
                else
                {
                    stream.ReadBytes(Pixels, 0, Pixels.Length);
                }
            }

            if (!flipped)
            {
                return;
            }

            for (var i = 0; i < Height; i++)
            {
                var row = new byte[Width];
                Array.Copy(Pixels, i * Width, row, 0, Width);
                Array.Reverse(row);
                Array.Copy(row, 0, Pixels, i * Width, Width);
            }
        }
Exemple #2
0
        public byte[] ApplyFrame(byte[] oldFrame, uint[] palette, int2 size)
        {
            var newFrame = new byte[oldFrame.Length];
            var offset   = globalMotion.X + globalMotion.Y * size.X;

            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 < size.Y / 4; by++)
            {
                for (var bx = 0; bx < size.X / 4;)
                {
                    var blockTypes = video.ReadUInt8();

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

                        switch (blockType)
                        {
                        case 0:
                        {
                            for (var y = 0; y < 4; y++)
                            {
                                var dst = (by * 4 + y) * size.X + bx * 4;
                                Array.Copy(oldFrame, dst + offset, newFrame, dst, 4);
                            }

                            break;
                        }

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

                            if (motion == 0)
                            {
                                for (var y = 0; y < 4; y++)
                                {
                                    Array.Copy(video.ReadBytes(4), 0, newFrame, (by * 4 + y) * size.X + bx * 4, 4);
                                }
                            }
                            else
                            {
                                var motionX = ((motion & 0xf) ^ 8) - 8;
                                var motionY = ((motion >> 4) ^ 8) - 8;

                                for (var y = 0; y < 4; y++)
                                {
                                    var dst = (by * 4 + y) * size.X + bx * 4;
                                    Array.Copy(oldFrame, dst + offset + motionY * size.X + motionX, newFrame, dst, 4);
                                }
                            }

                            break;
                        }

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

                            for (var y = 0; y < 4; y++)
                            {
                                for (var x = 0; x < 4; x++)
                                {
                                    newFrame[(by * 4 + y) * size.X + 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 = video.ReadUInt8();
                                var pixel1 = video.ReadUInt8();

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

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

                                for (var y = 0; y < 4; y++)
                                {
                                    for (var x = 0; x < 4; x++)
                                    {
                                        var dst = (by * 4 + y) * size.X + bx * 4 + x;

                                        if (((pattern >> (y * 4 + x)) & 1) == 0)
                                        {
                                            newFrame[dst] = oldFrame[dst + offset];
                                        }
                                        else
                                        {
                                            newFrame[dst] = pixel;
                                        }
                                    }
                                }

                                break;
                            }

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

                                for (var y = 0; y < 4; y++)
                                {
                                    for (var x = 0; x < 4; x++)
                                    {
                                        var dst = (by * 4 + y) * size.X + bx * 4 + x;

                                        if (((pattern >> (y * 4 + x)) & 1) == 1)
                                        {
                                            newFrame[dst] = oldFrame[dst + offset];
                                        }
                                        else
                                        {
                                            newFrame[dst] = pixel;
                                        }
                                    }
                                }

                                break;
                            }
                            }

                            break;
                        }
                        }
                    }
                }
            }

            return(newFrame);
        }
Exemple #3
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);
        }