Пример #1
0
        internal Lgr(string lgrFile)
        {
            using (var stream = File.OpenRead(lgrFile))
            {
                Path = lgrFile;
                var lgr = new BinaryReader(stream, Encoding.ASCII);
                if (lgr.ReadString(5) != "LGR12")
                {
                    throw new Exception($"The LGR file {lgrFile} is not valid (magic start string not found)");
                }
                int numberOfPcXs       = lgr.ReadInt32();
                int picturesLstVersion = lgr.ReadInt32(); // unused
                int numberOfOptPcXs    = lgr.ReadInt32();
                var pcxNames           = new List <string>();
                var pcxTypes           = new List <ImageType>();
                var distances          = new List <int>();
                var clippingTypes      = new List <ClippingType>();
                var transparencies     = new List <Transparency>();
                for (int i = 0; i < numberOfOptPcXs; i++)
                {
                    pcxNames.Add(lgr.ReadNullTerminatedString(10));
                }

                for (int i = 0; i < numberOfOptPcXs; i++)
                {
                    pcxTypes.Add((ImageType)lgr.ReadInt32());
                }

                for (int i = 0; i < numberOfOptPcXs; i++)
                {
                    distances.Add(lgr.ReadInt32());
                }

                for (int i = 0; i < numberOfOptPcXs; i++)
                {
                    clippingTypes.Add((ClippingType)lgr.ReadInt32());
                }

                for (int i = 0; i < numberOfOptPcXs; i++)
                {
                    transparencies.Add((Transparency)lgr.ReadInt32());
                }

                for (int i = 0; i < numberOfOptPcXs; i++)
                {
                    ListedImages.Add(new ListedImage
                    {
                        Name         = pcxNames[i].ToLower(),
                        Type         = pcxTypes[i],
                        Distance     = distances[i],
                        ClippingType = clippingTypes[i],
                        Transparency = transparencies[i]
                    });
                }

                for (int i = 0; i < numberOfPcXs; i++)
                {
                    string       lgrImageName    = System.IO.Path.GetFileNameWithoutExtension(lgr.ReadNullTerminatedString(12)).ToLower();
                    var          isGrass         = lgrImageName == "qgrass";
                    ImageType    imgType         = isGrass ? ImageType.Texture : ImageType.Picture;
                    int          imgDistance     = 500;
                    ClippingType imgClippingType = isGrass ? ClippingType.Ground : ClippingType.Unclipped;
                    var          transparency    = Transparency.TopLeft;
                    foreach (ListedImage x in ListedImages)
                    {
                        if (x.Name == lgrImageName)
                        {
                            imgType         = x.Type;
                            imgClippingType = x.ClippingType;
                            imgDistance     = x.Distance;
                            if (!TransparencyIgnoreSet.Contains(x.Name))
                            {
                                transparency = x.Transparency;
                            }
                        }
                    }

                    lgr.ReadInt32(); // unknown, not used
                    lgr.ReadInt32(); // unknown, not used
                    int    sizeOfPcx = lgr.ReadInt32();
                    Bitmap bmp       = new Pcx(stream).ToBitmap();
                    if (imgType != ImageType.Texture)
                    {
                        switch (transparency)
                        {
                        case Transparency.NotTransparent:
                            break;

                        case Transparency.Palette0:
                            bmp.MakeTransparent(Color.Black);     // TODO get from palette index 0
                            break;

                        // If the transparency field value is invalid, we'll assume Transparency.TopLeft as it is the most common case.
                        default:
                            // case Transparency.TopLeft:
                            bmp.MakeTransparent(bmp.GetPixel(0, 0));
                            break;

                        case Transparency.TopRight:
                            bmp.MakeTransparent(bmp.GetPixel(bmp.Width - 1, 0));
                            break;

                        case Transparency.BottomLeft:
                            bmp.MakeTransparent(bmp.GetPixel(0, bmp.Height - 1));
                            break;

                        case Transparency.BottomRight:
                            bmp.MakeTransparent(bmp.GetPixel(bmp.Width - 1, bmp.Height - 1));
                            break;
                        }
                    }

                    LgrImages.Add(new LgrImage(lgrImageName, bmp, imgType, imgDistance, imgClippingType));
                }
            }
        }
Пример #2
0
        internal Lgr(string lgrFile)
        {
            byte[] lgrData = File.ReadAllBytes(lgrFile);
            if (Encoding.ASCII.GetString(lgrData, 0, 5) != "LGR12")
            {
                throw (new Exception("The specified LGR file " + lgrFile + " is not valid!"));
            }
            int numberOfPcXs    = BitConverter.ToInt32(lgrData, 5);
            int numberOfOptPcXs = BitConverter.ToInt32(lgrData, 13);

            for (int i = 0; i < numberOfOptPcXs; i++)
            {
                ListedImages.Add(new ListedImage
                {
                    Name = Utils.ReadNullTerminatedString(lgrData, i * 10 + 17, 10).ToLower(),
                    Type =
                        (ImageType)
                        BitConverter.ToInt32(lgrData, 17 + numberOfOptPcXs * 10 + i * 4),
                    Distance     = BitConverter.ToInt32(lgrData, 17 + numberOfOptPcXs * 14 + i * 4),
                    ClippingType =
                        (ClippingType)
                        BitConverter.ToInt32(lgrData, 17 + numberOfOptPcXs * 18 + i * 4),
                    Transparency =
                        (Transparency)
                        BitConverter.ToInt32(lgrData, 17 + numberOfOptPcXs * 22 + i * 4)
                });
            }

            int sp = 17 + numberOfOptPcXs * 26;

            for (int i = 0; i < numberOfPcXs; i++)
            {
                string lgrImageName =
                    Path.GetFileNameWithoutExtension(Utils.ReadNullTerminatedString(lgrData, sp, 12)).ToLower();
                var          isGrass         = lgrImageName == "qgrass";
                ImageType    imgType         = isGrass ? ImageType.Texture : ImageType.Picture;
                int          imgDistance     = 500;
                ClippingType imgClippingType = isGrass ? ClippingType.Ground : ClippingType.Unclipped;
                var          transparency    = Transparency.TopLeft;
                foreach (ListedImage x in ListedImages)
                {
                    if (x.Name == lgrImageName)
                    {
                        imgType         = x.Type;
                        imgClippingType = x.ClippingType;
                        imgDistance     = x.Distance;
                        if (!TransparencyIgnoreSet.Contains(x.Name))
                        {
                            transparency = x.Transparency;
                        }
                    }
                }

                sp += 24;
                int    sizeOfPcx = BitConverter.ToInt32(lgrData, sp - 4);
                byte[] data      = new byte[sizeOfPcx];
                Array.ConstrainedCopy(lgrData, sp, data, 0, sizeOfPcx);
                MemoryStream memStream = new MemoryStream(data);
                try
                {
                    Bitmap bmp = new Pcx(memStream).ToBitmap();
                    if (imgType != ImageType.Texture)
                    {
                        switch (transparency)
                        {
                        case Transparency.NotTransparent:
                            break;

                        case Transparency.Palette0:
                            bmp.MakeTransparent(Color.Black);     // TODO get from palette index 0
                            break;

                        // If the transparency field value is invalid, we'll assume Transparency.TopLeft as it is the most common case.
                        default:
                            // case Transparency.TopLeft:
                            bmp.MakeTransparent(bmp.GetPixel(0, 0));
                            break;

                        case Transparency.TopRight:
                            bmp.MakeTransparent(bmp.GetPixel(bmp.Width - 1, 0));
                            break;

                        case Transparency.BottomLeft:
                            bmp.MakeTransparent(bmp.GetPixel(0, bmp.Height - 1));
                            break;

                        case Transparency.BottomRight:
                            bmp.MakeTransparent(bmp.GetPixel(bmp.Width - 1, bmp.Height - 1));
                            break;
                        }
                    }

                    LgrImages.Add(new LgrImage(lgrImageName, bmp, imgType, imgDistance, imgClippingType));
                }
                finally
                {
                    memStream.Close();
                }

                sp += sizeOfPcx;
            }
        }