Ejemplo n.º 1
0
        private void Run(Utility utility, string[] args)
        {
            const string prtFilename = "op2_art.prt";

            // HACK: The engine code assumes that Game.modData is set.
            Game.ModData = modData = utility.ModData;

            using (var stream = Game.ModData.DefaultFileSystem.Open(prtFilename))
            {
                framePalettes = LoadPalettes(stream);
                prtFile       = LoadGroups(stream, out var palettes);
            }

            WriteSequences();
            Console.WriteLine($"Wrote sequences file: {OutputFilename}");

            WriteActors();
            Console.WriteLine($"Wrote rules file: {RulesOutputFilename}");
            Console.WriteLine($"Wrote rules example file: {RulesExampleOutputFilename}");
        }
Ejemplo n.º 2
0
        PrtFile LoadImageHeader(Stream s, out Dictionary <int, uint[]> palettes)
        {
            var spriteCount = s.ReadUInt32();
            var h           = new PrtFile()
            {
                ImageCount  = (int)spriteCount,
                ImageHeader = new Op2Image[spriteCount]
            };

            palettes = new Dictionary <int, uint[]>();
            var rawFrames = h.ImageHeader;

            for (var f = 0; f < rawFrames.Length; f++)
            {
                var paddedWidth = s.ReadUInt32();
                var dataOffset  = s.ReadUInt32();
                var height      = s.ReadUInt32();
                var width       = s.ReadUInt32();
                var type        = s.ReadUInt16();
                var palette     = s.ReadUInt16();
                palettes.Add(f, framePalettes[palette]);

                var img = new Op2Image
                {
                    PaddedWidth = paddedWidth,
                    DataOffset  = dataOffset,
                    Height      = height,
                    Width       = width,
                    ImageType   = type,
                    Palette     = palette,
                };

                h.ImageHeader[f] = img;
            }

            h.AllGroupCount   = s.ReadInt32();
            h.AllFrameCount   = s.ReadInt32();
            h.AllPicCount     = s.ReadInt32();
            h.AllExtInfoCount = s.ReadInt32();
            return(h);
        }
Ejemplo n.º 3
0
        public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
        {
            var start = s.Position;

            var signature = s.ReadASCII(2);

            if (signature != "BM")
            {
                s.Position = start;
                metadata   = null;
                frames     = null;
                return(false);
            }

            var size      = s.ReadUInt32();
            var reserved1 = s.ReadUInt16();
            var reserved2 = s.ReadUInt16();
            var dataStart = s.ReadUInt32();

            var prt = Game.ModData.DefaultFileSystem.Open("op2_art.prt");

            framePalettes = LoadPalettes(prt);
            prtFile       = LoadImageHeader(prt, out var palettes);
            var frameList = new List <ISpriteFrame>();

            // Populate art data
            const byte shadowTileIndex = 1;
            var        imgIndex        = 0;

            foreach (var img in prtFile.ImageHeader)
            {
                var isShadow = img.ImageType == 4 || img.ImageType == 5;

                var dataSize  = new Size((int)img.PaddedWidth, (int)img.Height);
                var frameSize = new Size((int)img.Width, (int)img.Height);
                s.Seek(dataStart + img.DataOffset, SeekOrigin.Begin);

                byte[] data;
                var    numBytes = (int)(img.PaddedWidth * img.Height);

                if (isShadow)
                {
                    var       newSize       = (int)(img.PaddedWidth * img.Height);
                    var       rowSize       = (int)Math.Pow(2, Math.Ceiling(Math.Log(img.Width) / Math.Log(2)));
                    var       hasExtraRow   = rowSize == (int)img.PaddedWidth;
                    var       tempData      = s.ReadBytes(numBytes);
                    var       bits          = new BitArray(tempData);
                    var       processedData = new byte[newSize * 8];
                    var       paddedWidth   = img.Width;
                    const int bitsInAByte   = 8;
                    var       numRows       = (int)img.Height * 2;         // TODO: This is a hack. Not sure why we need to double this
                    if (hasExtraRow)
                    {
                        numRows *= 2;
                    }

                    // HACK: HACK HACK HACK
                    // Obviously our rowSize calculation is borked, so correct some things here
                    if (rowSize < 32)
                    {
                        rowSize = 32;
                    }

                    if (img.ImageType == 5)
                    {
                        if (rowSize == 128)
                        {
                            rowSize = 96;
                        }
                        else if (rowSize == 256)
                        {
                            rowSize = 128;
                        }
                    }

                    for (var y = 0; y < numRows; y++)
                    {
                        for (var x = 0; x < img.Width; x++)
                        {
                            var i = (int)((y * paddedWidth) + x);
                            var reversedBitIndex = 7 - (i % bitsInAByte);
                            var byteFloor        = i - (i % bitsInAByte);

                            var lookupIndex = byteFloor + reversedBitIndex;
                            processedData[i] = (byte)(bits[lookupIndex] ? shadowTileIndex : 0);
                        }
                    }

                    var paddedDiff = (int)(img.PaddedWidth - img.Width);
                    var newData    = new List <byte>();

                    for (var i = 0; i < img.Height; i++)
                    {
                        var startIndex = i * rowSize;

                        var firstX = processedData.Skip(startIndex).Take((int)img.Width).ToArray();
                        newData.AddRange(firstX);
                        newData.AddRange(Enumerable.Repeat <byte>(0, paddedDiff));

                        // if (imgIndex == 1758)
                        // {
                        //  var ss = imgIndex;
                        // }
                    }

                    if (img.PaddedWidth * img.Height > newData.Count)
                    {
                        throw new ArgumentException("Image size did not match number of bytes.");
                    }

                    data = newData.ToArray();
                }
                else
                {
                    data = s.ReadBytes(numBytes);
                }

                img.SpriteFrame = new BitmapSpriteFrame
                {
                    Size      = dataSize,
                    FrameSize = frameSize,
                    Data      = data,
                    Type      = SpriteFrameType.Indexed,
                };
                frameList.Add(img.SpriteFrame);

                imgIndex++;
            }

            metadata = new TypeDictionary {
                new EmbeddedSpritePalette(framePalettes: palettes)
            };

            frames = frameList.ToArray();

            return(true);
        }
Ejemplo n.º 4
0
        private bool IsPrt(Stream s)
        {
            var start = s.Position;
            var h     = new PrtFile()
            {
                ID       = s.ReadASCII(4),
                PalCount = s.ReadInt32(),
            };

            if (h.ID != "CPAL")
            {
                s.Position = start;
                return(false);
            }

            h.PalData = new Ppal[h.PalCount];

            // Parse palettes
            for (var i = 0; i < h.PalCount; i++)
            {
                var ppal = new Ppal
                {
                    ID            = s.ReadASCII(4),
                    Size          = s.ReadInt32(),
                    HeadID        = s.ReadASCII(4),
                    BytesPerEntry = s.ReadInt32(),
                    Unknown       = s.ReadInt32(),
                    DataID        = s.ReadASCII(4),
                    PalSize       = s.ReadInt32()
                };

                if (ppal.ID != "PPAL" || ppal.HeadID != "head" || ppal.DataID != "data")
                {
                    s.Position = start;
                    return(false);
                }

                var numPaletteEntries = ppal.PalSize / ppal.BytesPerEntry;

                ppal.PaletteData = new RgbQuad[numPaletteEntries];

                // Populate palette
                for (var j = 0; j < numPaletteEntries; j++)
                {
                    var rgba = new RgbQuad
                    {
                        Red      = s.ReadByte(),
                        Green    = s.ReadByte(),
                        Blue     = s.ReadByte(),
                        Reserved = s.ReadByte(),
                    };

                    ppal.PaletteData[j] = rgba;
                }

                h.PalData[i] = ppal;
            }

            h.ImageCount  = s.ReadInt32();
            h.ImageHeader = new Op2Image[h.ImageCount];

            for (var i = 0; i < h.ImageCount; i++)
            {
                var img = new Op2Image
                {
                    SizeScanline = s.ReadInt32(),
                };

                img.ImgData      = s.ReadBytes(img.SizeScanline);
                img.SizeX        = s.ReadInt32();
                img.SizeY        = s.ReadInt32();
                img.Unknown      = s.ReadInt16();
                img.Palette      = s.ReadInt16();
                h.ImageHeader[i] = img;
            }

            h.AllGroupCount   = s.ReadInt32();
            h.AllFrameCount   = s.ReadInt32();
            h.AllPicCount     = s.ReadInt32();
            h.AllExtInfoCount = s.ReadInt32();
            h.Groups          = new ImageGroup[h.AllGroupCount];

            for (var i = 0; i < h.AllGroupCount; i++)
            {
                var img = new ImageGroup
                {
                    Unknown1   = s.ReadInt32(),
                    SelLeft    = s.ReadInt32(),
                    SelTop     = s.ReadInt32(),
                    SelRight   = s.ReadInt32(),
                    SelBottom  = s.ReadInt32(),
                    CenterX    = s.ReadInt32(),
                    CenterY    = s.ReadInt32(),
                    Unknown8   = s.ReadInt32(),
                    FrameCount = s.ReadInt32()
                };

                img.Frames = new Op2Frame[img.FrameCount];

                for (var j = 0; j < img.FrameCount; j++)
                {
                    var frame = new Op2Frame
                    {
                        PicCount = s.ReadUInt8(),
                        Unknown  = s.ReadUInt8(),
                    };

                    frame.ExtUnknown1 = new BytePair[frame.PicCount >> 7];
                    for (var k = 0; k < frame.PicCount >> 7; k++)
                    {
                        var bp = new BytePair
                        {
                            Byte1 = s.ReadUInt8(),
                            Byte2 = s.ReadUInt8(),
                        };

                        frame.ExtUnknown1[k] = bp;
                    }

                    frame.ExtUnknown2 = new BytePair[frame.Unknown >> 7];
                    for (var k = 0; k < frame.Unknown >> 7; k++)
                    {
                        var bp = new BytePair
                        {
                            Byte1 = s.ReadUInt8(),
                            Byte2 = s.ReadUInt8(),
                        };

                        frame.ExtUnknown2[k] = bp;
                    }

                    frame.Pictures = new Op2Picture[frame.PicCount & 0x7F];
                    for (var k = 0; k < frame.Pictures.Length; k++)
                    {
                        var pic = new Op2Picture
                        {
                            ImgNumber = s.ReadInt16(),
                            Reserved  = s.ReadUInt8(),
                            PicOrder  = s.ReadUInt8(),
                            PosX      = s.ReadInt16(),
                            PosY      = s.ReadInt16()
                        };

                        frame.Pictures[k] = pic;
                    }

                    img.Frames[j] = frame;
                }

                img.GroupExtCount = s.ReadInt32();
                img.Extended      = new GroupExt[img.GroupExtCount];

                for (var j = 0; j < img.GroupExtCount; j++)
                {
                    var ext = new GroupExt
                    {
                        Unknown1 = s.ReadInt32(),
                        Unknown2 = s.ReadInt32(),
                        Unknown3 = s.ReadInt32(),
                        Unknown4 = s.ReadInt32(),
                    };

                    img.Extended[j] = ext;
                }

                h.Groups[i] = img;
            }

            file = h;

            return(true);
        }
Ejemplo n.º 5
0
 public Op2SpriteFrame(Stream s, PrtFile head, Op2SpriteFrameInfo info)
 {
     /*
      * Type = SpriteFrameType.Indexed;
      * var picindex = info.A * sph.Nrots + info.R;
      * var readInt = new Func<int, int>((off) =>
      * {
      *      s.Position = off;
      *      return s.ReadInt32();
      * });
      *
      * var picnr = readInt(HeaderSize + picindex * 4);
      * if (picnr >= sph.Npics)
      *      throw new Exception("Pic number was greater or equal to number of pics.");
      *
      * var picoff = readInt(sph.OffPicoffs + 8 * picnr);
      * var nextpicoff = readInt(sph.OffPicoffs + 8 * (picnr + 1));
      * var start = s.Position;
      * s.Position = sph.OffBits + picoff;
      * var tempData = s.ReadBytes(nextpicoff - picoff);
      * Data = new byte[(sph.Szx + 2) * sph.Szy];
      *
      * var pixindex = new Func<int, int, int>((x, y) =>
      * {
      *      int vr = (y * sph.Szx) + x;
      *      return vr;
      * });
      *
      * var curr = 0;
      * for (var l = 0; l < sph.Szy; ++l)
      * {
      *      int step = 0, currx = 0, cnt, i;
      *      while (currx < sph.Szx)
      *      {
      *              cnt = tempData[curr++];
      *              if ((step & 1) != 0)
      *                      cnt &= 0x7f;
      *              if ((step & 1) != 0)
      *              {
      *                      if (!sph.IsShadow)
      *                      {
      *                              for (i = 0; i < cnt; ++i, ++curr)
      *                              {
      *                                      int newIndex = pixindex(currx + i, l);
      *                                      Data[newIndex] = tempData[curr];
      *                              }
      *                      }
      *                      else
      *                      {
      *                              for (i = 0; i < cnt; ++i)
      *                              {
      *                                      int newIndex = pixindex(currx + i, l);
      *                                      Data[newIndex] = 47;
      *                              }
      *                      }
      *              }
      *
      *              currx += cnt;
      ++step;
      *      }
      *
      *      if (currx != sph.Szx)
      *              throw new Exception("Current x was not equal to the line size.");
      * }
      *
      * Offset = new float2(0, 0);
      * FrameSize = new Size(sph.Szx, sph.Szy);
      * Size = FrameSize;
      *
      * s.Position = start;
      */
 }
Ejemplo n.º 6
0
        private static void Convert(string f)
        {
            string magic;

            using (FileStream fs = File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                BrgBinaryReader reader = new BrgBinaryReader(EndianBitConverter.Little, fs);
                magic = reader.ReadString(4);
            }

            if (f.EndsWith("anim.txt"))
            {
                AnimFile.ConvertToXml(File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read), File.Open(f + ".xml", FileMode.Create, FileAccess.Write, FileShare.Read));
                Console.WriteLine("Success! Anim converted.");
            }
            else if (f.EndsWith(".prt"))
            {
                PrtFile file = new PrtFile(File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read));
                file.SerializeAsXml(File.Open(f + ".xml", FileMode.Create, FileAccess.Write, FileShare.Read));
                Console.WriteLine("Success! Prt converted.");
            }
            else if (magic == "MTRL")
            {
                MtrlFile file = new MtrlFile();
                file.Read(File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read));
                file.SerializeAsXml(File.Open(f + ".xml", FileMode.Create, FileAccess.Write, FileShare.Read));
                Console.WriteLine("Success! Mtrl converted.");
            }
            else if (magic == "BANG")
            {
                string brgMtrlOutputPath = Path.Combine(Path.GetDirectoryName(f), "materials");
                if (!Directory.Exists(brgMtrlOutputPath))
                {
                    Directory.CreateDirectory(brgMtrlOutputPath);
                }

                BrgFile file = new BrgFile(File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read));
                for (int i = 0; i < file.Materials.Count; ++i)
                {
                    MtrlFile mtrl = new MtrlFile(file.Materials[i]);
                    mtrl.Write(File.Open(Path.Combine(brgMtrlOutputPath, Path.GetFileNameWithoutExtension(f) + "_" + i + ".mtrl"), FileMode.Create, FileAccess.Write, FileShare.Read));
                }
                Console.WriteLine("Success! Mtrl files created.");
            }
            else
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(f);

                if (xmlDoc.DocumentElement.Name == "AnimFile")
                {
                    AnimFile.ConvertToAnim(File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read), File.Open(f + ".txt", FileMode.Create, FileAccess.Write, FileShare.Read));
                    Console.WriteLine("Success! Anim converted.");
                }
                else if (xmlDoc.DocumentElement.Name == "ParticleFile")
                {
                    PrtFile file = PrtFile.DeserializeAsXml(File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read));
                    file.Write(File.Open(f + ".prt", FileMode.Create, FileAccess.Write, FileShare.Read));
                    Console.WriteLine("Success! Prt converted.");
                }
                else
                {
                    MtrlFile file = MtrlFile.DeserializeAsXml(File.Open(f, FileMode.Open, FileAccess.Read, FileShare.Read));
                    file.Write(File.Open(f + ".mtrl", FileMode.Create, FileAccess.Write, FileShare.Read));
                    Console.WriteLine("Success! Mtrl converted.");
                }
            }
        }