Beispiel #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);
            }
        }
Beispiel #2
0
        public Mobd(SegmentStream stream, Version version)
        {
            var fileOffset          = (uint)stream.BaseOffset;
            var firstFrameStart     = stream.Length;
            var justReadFrameOffset = false;

            var animationOffsets     = new List <uint>();
            var rotationalAnimations = new List <MobdAnimation>();
            var simpleAnimations     = new List <MobdAnimation>();

            while (stream.Position < firstFrameStart)
            {
                var value = stream.ReadUInt32();

                // This parsing method is trash, because animation offsets are hardcoded in .exe but it seems to work.
                if ((value == 0xffffffff || value == 0x00000000) && justReadFrameOffset)
                {
                    // terminator
                    justReadFrameOffset = false;
                }
                else if (value - fileOffset > stream.Position && value - fileOffset < stream.Length)
                {
                    // frame
                    justReadFrameOffset = true;
                    firstFrameStart     = Math.Min(firstFrameStart, value - fileOffset);
                }
                else if (value - fileOffset < stream.Position && value >= fileOffset)
                {
                    // animation pointer
                    animationOffsets.Remove(value - fileOffset);
                    var returnPosition = stream.Position;
                    stream.Position = value - fileOffset;
                    rotationalAnimations.Add(new MobdAnimation(stream, version));
                    stream.Position = returnPosition;
                }
                else if (value == 0)
                {
                    // TODO filler ? Sprite Invisible?
                }
                else
                {
                    animationOffsets.Add((uint)(stream.Position - 4));
                }
            }

            foreach (var animationOffset in animationOffsets)
            {
                try
                {
                    stream.Position = animationOffset;
                    simpleAnimations.Add(new MobdAnimation(stream, version));
                }
                catch (Exception)
                {
                    // TODO crashes on kknd2, fix me!
                }
            }

            RotationalAnimations = rotationalAnimations.ToArray();
            SimpleAnimations     = simpleAnimations.ToArray();
        }