/// <summary>
        /// Constructs a list of mini-animations from a file stream, starting with the beginning pointer table.
        /// </summary>
        /// <param name="stream">Stream to read from, starting with a pointer table to sub-mini anims.</param>
        public MiniAnimGroup(Stream stream)
        {
            Pointer = stream.Position;
            int firstAnimPointer = int.MaxValue;

            while (stream.Position < firstAnimPointer + Pointer)
            {
                int animationPointer = BNSAFile.ReadIntegerFromStream(stream);
                firstAnimPointer = Math.Min(firstAnimPointer, animationPointer); //should only be triggered by the first pointer as it goes ascending.
                long nextPosition = stream.Position;
                stream.Seek(Pointer + animationPointer, SeekOrigin.Begin);       //Move cursor to start of minianim
                MiniAnim animation = new MiniAnim(stream, Pointer);
                IsValid &= animation.IsValid;
                if (!IsValid)
                {
                    break; //Invalid data, stop caring and exit.
                }

                MiniAnimations.Add(animation);
                if (nextPosition < firstAnimPointer + Pointer)
                {
                    //Read the next 4 bytes in the pointer table as its a new pointer
                    stream.Seek(nextPosition, SeekOrigin.Begin);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Reads a project XML file and relinks all the parts for file rebuilding
        /// </summary>
        /// <param name="filePath">XML file to parse</param>
        public BNSAXMLFile(string filePath)
        {
            this.FilePath = filePath;
            Console.WriteLine("Loading project file: " + filePath);
            XmlDocument doc = new XmlDocument();

            doc.Load(filePath);

            //Parse Process:
            //1. Read animation tree
            //2. Read tileset folder
            //3. Read minianim folder
            //4. Read palette folder
            //5. Read oamdatalists folder
            //6. Link all objects

            //Build lists, mark pointer placeholders
            //Byte align after lists are built
            //insert pointers
            //merge into single file

            string tilesetBasepath      = Directory.GetParent(filePath).FullName + "\\tilesets\\tileset";
            string palettesBasepath     = Directory.GetParent(filePath).FullName + "\\palettes\\palette";
            string oamDataListsBasepath = Directory.GetParent(filePath).FullName + "\\oamdatalists\\oamdatalist";
            string miniAnimsBasepath    = Directory.GetParent(filePath).FullName + "\\minianims\\minianim";



            XmlNodeList animationNodes = doc.DocumentElement.SelectNodes("/bnsafile/animations/animation");

            Console.WriteLine("Found " + animationNodes.Count + " animations");
            Animations = new List <Animation>();
            foreach (XmlNode animationNode in animationNodes)
            {
                //Read Animation XML
                Animation animation = new Animation(animationNode);
                //Verify references exist in filesystem
                foreach (Frame f in animation.Frames)
                {
                    //Verify Tileset
                    string tilesetPath = tilesetBasepath + f.TilesetIndex.ToString().PadLeft(3, '0') + ".bin";
                    if (!File.Exists(tilesetPath))
                    {
                        IsValid = false;
                        Console.WriteLine("Tileset file missing: " + tilesetPath + ", referenced by Anim " + animation.Index + " frame " + f.Index);
                        return;
                    }

                    //Verify OAM
                    string oamPath = oamDataListsBasepath + f.OAMDataListIndex + "-0-0.bin";
                    if (!File.Exists(oamPath))
                    {
                        IsValid = false;
                        Console.WriteLine("OAM Data List file missing: " + oamPath + ", referenced by Anim " + animation.Index + " frame " + f.Index);
                        return;
                    }

                    //Verify MiniAnim
                    string minianimFrame1 = miniAnimsBasepath + f.MiniAnimationIndex + "-0-0.bin";
                    if (!File.Exists(minianimFrame1))
                    {
                        IsValid = false;
                        Console.WriteLine("MiniAnimation file missing: " + minianimFrame1 + ", referenced by Anim " + animation.Index + " frame " + f.Index);
                        return;
                    }
                }
                Animations.Add(animation);
                Console.WriteLine("OK - animation contains all direct binary references");
            }
            //Read Tilesets
            Tilesets = new List <Tileset>();
            int index = 0;

            for (int i = 0; i < 999; i++)
            {
                string tilesetPath = tilesetBasepath + index.ToString().PadLeft(3, '0') + ".bin";
                if (File.Exists(tilesetPath))
                {
                    Tileset tileset = new Tileset(tilesetPath, i);
                    Tilesets.Add(tileset);
                }
                else
                {
                    break; //No more tilesets
                }
                index++;
            }
            Console.WriteLine("Read " + Tilesets.Count + " tilesets");

            //Read Palettes
            Palettes = new List <Palette>();
            for (int i = 0; i < 16; i++)
            {
                string palettePath = palettesBasepath + i.ToString().PadLeft(2, '0') + ".bin";
                if (File.Exists(palettePath))
                {
                    Palette palette = new Palette(palettePath);
                    Palettes.Add(palette);
                }
                else
                {
                    break; //No more palettes
                }
            }
            Console.WriteLine("Read " + Palettes.Count + " palettes");

            //Read MiniAnims
            string[] miniAnimFiles = Directory.GetFiles(Directory.GetParent(filePath).FullName + "\\minianims");
            int      maxindex      = 0;

            foreach (string file in miniAnimFiles)
            {
                string fname = Path.GetFileNameWithoutExtension(file);
                fname = fname.Substring(8);
                int dashIndex = fname.IndexOf('-');
                fname    = fname.Substring(0, dashIndex);
                maxindex = Math.Max(maxindex, Int32.Parse(fname));
            }
            Console.WriteLine("Found " + (maxindex + 1) + " mini animations");
            MiniAnimationGroups = new List <MiniAnimGroup>();
            for (index = 0; index <= maxindex; index++)
            {
                int subindex = 0;
                Console.WriteLine("Parsing Group " + index);
                MiniAnimGroup group = new MiniAnimGroup(index);
                while (File.Exists(miniAnimsBasepath + maxindex + "-" + subindex + "-0.bin"))
                {
                    //MiniAnimation List
                    MiniAnim animation = new MiniAnim(miniAnimsBasepath, index, subindex);
                    group.MiniAnimations.Add(animation);
                    subindex++;
                }
                MiniAnimationGroups.Add(group);
            }

            //Read OAM Data
            string[] oamListEntries = Directory.GetFiles(Directory.GetParent(filePath).FullName + "\\oamdatalists");
            maxindex = 0;
            foreach (string file in oamListEntries)
            {
                string fname = Path.GetFileNameWithoutExtension(file);
                fname = fname.Substring(11);
                int dashIndex = fname.IndexOf('-');
                fname    = fname.Substring(0, dashIndex);
                maxindex = Math.Max(maxindex, Int32.Parse(fname));
            }
            Console.WriteLine("Found " + (maxindex + 1) + " OAM Data List Groups");
            OAMDataListGroups = new List <OAMDataListGroup>();
            for (int i = 0; i <= maxindex; i++)
            {
                Console.WriteLine("Parsing OAM Data List Group " + i);
                OAMDataListGroup list = new OAMDataListGroup(oamDataListsBasepath, i);
                OAMDataListGroups.Add(list);
            }
            IsValid = true;
        }