Esempio n. 1
0
        private MphdRecord ReadChunkMPHD(Stream stream, Chunk chunk)
        {
            MphdRecord mphdRecord = new MphdRecord();

            stream.Position = chunk.FilePosition;
            mphdRecord.VersionHigh = ReadSignedByte(stream);
            mphdRecord.VersionLow = ReadSignedByte(stream);
            mphdRecord.LSB = ReadSignedByte(stream) != 0;
            mphdRecord.MapType = ReadSignedByte(stream);

            if (mphdRecord.MapType != 0)
                throw new Exception("Only MapType = 0 is supported");

            mphdRecord.MapWidth = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.MapHeight = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.Reserved1 = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.Reserved2 = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.BlockWidth = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.BlockHeight = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.BlockDepth = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.BlockStructSize = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.NumBlockStruct = ReadShort(stream, mphdRecord.LSB);
            mphdRecord.NumBlockGfx = ReadShort(stream, mphdRecord.LSB);

            if (chunk.Length > 24)
            {
                mphdRecord.ColourKeyIndex = ReadUnsignedByte(stream);
                mphdRecord.ColourKeyRed = ReadUnsignedByte(stream);
                mphdRecord.ColourKeyGreen = ReadUnsignedByte(stream);
                mphdRecord.ColourKeyBlue = ReadUnsignedByte(stream);

                if (chunk.Length > 28)
                {
                    mphdRecord.BlockGapX = ReadShort(stream, mphdRecord.LSB);
                    mphdRecord.BlockGapY = ReadShort(stream, mphdRecord.LSB);
                    mphdRecord.BlockStaggerX = ReadShort(stream, mphdRecord.LSB);
                    mphdRecord.BlockStaggerY = ReadShort(stream, mphdRecord.LSB);

                    if (chunk.Length > 36)
                    {
                        mphdRecord.ClickMask = ReadShort(stream, mphdRecord.LSB);
                        mphdRecord.Pillars = ReadShort(stream, mphdRecord.LSB);
                    }
                }
            }

            return mphdRecord;
        }
Esempio n. 2
0
 private short[] ReadChunkLayer(Stream stream, Chunk chunk, MphdRecord mphdRecord)
 {
     bool lsb = mphdRecord.LSB;
     short[] offsets = new short[chunk.Length / 2];
     stream.Position = chunk.FilePosition;
     for (int index = 0; index < offsets.Length; index++)
     {
         short offset = ReadShort(stream, lsb);
         if (mphdRecord.VersionHigh < 1)
         {
             if (offset >= 0)
                 offset /= mphdRecord.BlockStructSize;
             else
                 offset /= AnimationRecord.SIZE;
         }
         offsets[index] = offset;
     }
     return offsets;
 }
Esempio n. 3
0
        private Image ReadChunkBGFX(Stream stream, Chunk chunk, MphdRecord mphdRecord, Color[] colourMap)
        {
            int tileCount = mphdRecord.NumBlockStruct;
            int imageWidth = mphdRecord.BlockWidth;
            int imageHeight = mphdRecord.BlockHeight * tileCount;

            byte[] imageData = new byte[chunk.Length];
            stream.Position = chunk.FilePosition;
            stream.Read(imageData, 0, chunk.Length);

            bool applyColourKeying = false;
            if (mphdRecord.BlockDepth < 32)
            {
                applyColourKeying = MessageBox.Show(
                    "Apply colour keying?", "Mappy BGFX Chunk",
                    MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes;
            }

            Bitmap imageSource = new Bitmap(imageWidth, imageHeight, PixelFormat.Format32bppArgb);
            int pixelIndex = 0;
            if (mphdRecord.BlockDepth == 8)
            {
                for (int pixelY = 0; pixelY < imageHeight; pixelY++)
                {
                    for (int pixelX = 0; pixelX < imageWidth; pixelX++)
                    {
                        byte colourIndex = imageData[pixelIndex++];
                        if (!applyColourKeying || colourIndex != mphdRecord.ColourKeyIndex)
                            imageSource.SetPixel(pixelX, pixelY, colourMap[colourIndex]);
                    }
                }
            }
            else if (mphdRecord.BlockDepth == 15)
            {
                for (int pixelY = 0; pixelY < imageHeight; pixelY++)
                {
                    for (int pixelX = 0; pixelX < imageWidth; pixelX++)
                    {
                        ushort colourValue = (ushort)(imageData[pixelIndex++] | (imageData[pixelIndex++] << 8));
                        byte alpha = 255;
                        byte red = (byte)(colourValue & 31);
                        byte green = (byte)((colourValue >> 5) & 31);
                        byte blue = (byte)((colourValue >> 10) & 31);
                        red *= 4;
                        green *= 4;
                        blue *= 4;
                        if (applyColourKeying
                            && red == mphdRecord.ColourKeyRed
                            && green == mphdRecord.ColourKeyGreen
                            && blue == mphdRecord.ColourKeyBlue)
                            alpha = 0;
                        Color colour = Color.FromArgb(alpha, red, green, blue);
                        imageSource.SetPixel(pixelX, pixelY, colour);
                    }
                }
            }
            else if (mphdRecord.BlockDepth == 16)
            {
                for (int pixelY = 0; pixelY < imageHeight; pixelY++)
                {
                    for (int pixelX = 0; pixelX < imageWidth; pixelX++)
                    {
                        ushort colourValue = (ushort)(imageData[pixelIndex++] | (imageData[pixelIndex++] << 8));
                        byte alpha = 255;
                        byte red = (byte)(colourValue & 31);
                        byte green = (byte)((colourValue >> 5) & 63);
                        byte blue = (byte)((colourValue >> 11) & 31);
                        red *= 8;
                        green *= 4;
                        blue *= 8;
                        if (applyColourKeying
                            && red == mphdRecord.ColourKeyRed
                            && green == mphdRecord.ColourKeyGreen
                            && blue == mphdRecord.ColourKeyBlue)
                            alpha = 0;
                        Color colour = Color.FromArgb(alpha, red, green, blue);
                        imageSource.SetPixel(pixelX, pixelY, colour);
                    }
                }
            }
            else if (mphdRecord.BlockDepth == 24)
            {
                for (int pixelY = 0; pixelY < imageHeight; pixelY++)
                {
                    for (int pixelX = 0; pixelX < imageWidth; pixelX++)
                    {
                        byte alpha = 255;
                        byte red   = imageData[pixelIndex++];
                        byte green = imageData[pixelIndex++];
                        byte blue  = imageData[pixelIndex++];
                        if (applyColourKeying
                            && red == mphdRecord.ColourKeyRed
                            && green == mphdRecord.ColourKeyGreen
                            && blue == mphdRecord.ColourKeyBlue)
                            alpha = 0;
                        Color colour = Color.FromArgb(alpha, red, green, blue);
                        imageSource.SetPixel(pixelX, pixelY, colour);
                    }
                }
            }
            else if (mphdRecord.BlockDepth == 32)
            {
                for (int pixelY = 0; pixelY < imageHeight; pixelY++)
                {
                    for (int pixelX = 0; pixelX < imageWidth; pixelX++)
                    {
                        byte alpha = imageData[pixelIndex++];
                        byte red = imageData[pixelIndex++];
                        byte green = imageData[pixelIndex++];
                        byte blue = imageData[pixelIndex++];
                        Color colour = Color.FromArgb(alpha, red, green, blue);
                        imageSource.SetPixel(pixelX, pixelY, colour);
                    }
                }
            }

            return imageSource;
        }
Esempio n. 4
0
        private BlockRecord[] ReadChunkBKDT(Stream stream, Chunk chunk, MphdRecord mphdRecord)
        {
            BlockRecord[] blockRecords = new BlockRecord[mphdRecord.NumBlockStruct];
            bool lsb = mphdRecord.LSB;
            for(int index = 0; index < mphdRecord.NumBlockStruct; index++)
            {
                stream.Position = chunk.FilePosition + mphdRecord.BlockStructSize * index;

                BlockRecord blockRecord = new BlockRecord();
                blockRecord.BackgroundOffset = ReadSignedLong(stream, lsb);
                blockRecord.ForegroundOffset = ReadSignedLong(stream, lsb);
                blockRecord.BackgroundOffset2 = ReadSignedLong(stream, lsb);
                blockRecord.ForegroundOffset2 = ReadSignedLong(stream, lsb);
                blockRecord.User1 = ReadUnsignedLong(stream, lsb);
                blockRecord.User2 = ReadUnsignedLong(stream, lsb);
                blockRecord.User3 = ReadUnsignedShort(stream, lsb);
                blockRecord.User4 = ReadUnsignedShort(stream, lsb);
                blockRecord.User5 = ReadUnsignedByte(stream);
                blockRecord.User6 = ReadUnsignedByte(stream);
                blockRecord.User7 = ReadUnsignedByte(stream);
                blockRecord.Flags = ReadUnsignedByte(stream);
                blockRecords[index] = blockRecord;
            }

            return blockRecords;
        }
Esempio n. 5
0
        private AnimationRecord[] ReadChunkANDT(Stream stream, Chunk chunk, MphdRecord mphdRecord)
        {
            bool lsb = mphdRecord.LSB;

            // count structures backwards
            stream.Position = chunk.FilePosition + chunk.Length - AnimationRecord.SIZE;
            int animationCount = 0;
            while (ReadSignedByte(stream) != -1)
            {
                ++animationCount;
                stream.Position -= (AnimationRecord.SIZE + 1);
            }

            AnimationRecord[] animationRecords = new AnimationRecord[animationCount];

            stream.Position = chunk.FilePosition + chunk.Length - AnimationRecord.SIZE;
            int animationIndex = 0;
            while (true)
            {
                long recordPosition = stream.Position;
                AnimationRecord animationRecord = new AnimationRecord();

                animationRecord.Type = ReadSignedByte(stream);
                if (animationRecord.Type == -1)
                    break;

                animationRecord.Delay = ReadSignedByte(stream);
                animationRecord.Counter = ReadSignedByte(stream);
                animationRecord.UserInfo = ReadSignedByte(stream);
                animationRecord.CurrentOffset = ReadSignedLong(stream, lsb);
                animationRecord.StartOffset = ReadSignedLong(stream, lsb);
                animationRecord.EndOffset = ReadSignedLong(stream, lsb);

                // offsets are negative offsets into a list of frame indices (32bit) at the beginning of the chunk
                int frameCount = (int)((animationRecord.EndOffset - animationRecord.StartOffset) / 4);

                // move (backwards) to frame indices at beginning of chunk
                animationRecord.Frames = new int[frameCount];
                //stream.Position += animationRecord.StartOffset;
                stream.Position = chunk.FilePosition + chunk.Length + animationRecord.StartOffset;
                for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                {
                    animationRecord.Frames[frameIndex] = (int)ReadSignedLong(stream, lsb);
                    if (mphdRecord.VersionHigh < 1)
                         animationRecord.Frames[frameIndex] /= mphdRecord.BlockStructSize;
                }

                animationRecords[animationIndex++] = animationRecord;

                stream.Position = recordPosition - AnimationRecord.SIZE;
            }

            stream.Position = chunk.FilePosition + chunk.Length;

            return animationRecords;
        }