示例#1
0
        public void ExportTex(string filename)
        {
            FileOutput o = new FileOutput();

            o.endian = Endianness.Little;

            o.WriteInt(pictureBox1.Image.Width);
            o.WriteInt(pictureBox1.Image.Height);
            o.WriteByte(formatSelector.SelectedIndex);
            o.WriteByte(1);
            o.WriteShort(0);
            o.WriteString(nameBox.Text);
            for (int i = 0; i < 0x74 - nameBox.Text.Length; i++)
            {
                o.WriteByte(0);
            }

            pictureBox1.Image.RotateFlip(RotateFlipType.RotateNoneFlipY);

            o.WriteBytes(_3DS.EncodeImage(new Bitmap(pictureBox1.Image), (_3DS.Tex_Formats)formatSelector.SelectedIndex));

            pictureBox1.Image.RotateFlip(RotateFlipType.RotateNoneFlipY);

            o.Save(filename);
        }
示例#2
0
 private void injectRom(object sender, EventArgs e)
 {
     using (OpenFileDialog ofd = new OpenFileDialog())
     {
         ofd.Title = "Select NES ROM";
         if (ofd.ShowDialog() == DialogResult.OK)
         {
             using (SaveFileDialog sfd = new SaveFileDialog())
             {
                 sfd.Title = "Select Save Location";
                 if (sfd.ShowDialog() == DialogResult.OK)
                 {
                     byte[]     rom = File.ReadAllBytes(ofd.FileName);
                     FileOutput f   = new FileOutput();
                     f.endian = Endianness.Little;
                     f.WriteInt(0);
                     f.WriteInt(0x30 + rom.Length);
                     f.WriteInt(0x30);
                     f.WriteInt(0x10 + rom.Length);
                     f.WriteInt(0x30 + rom.Length);
                     f.WriteInt(0);
                     f.WriteInt(0x1B + rom.Length);
                     f.WriteInt(0x1B + rom.Length);
                     f.WriteString("JAM WAS HERE");
                     f.WriteInt(0);
                     f.WriteBytes(rom);
                     f.WriteHex("3C00000000001000090002080000000100000000000000000000000000000000");
                     f.Save(sfd.FileName);
                 }
             }
         }
     }
 }
示例#3
0
        private void SaveMaterialToFile(string fileName)
        {
            FileOutput m = new FileOutput();
            FileOutput s = new FileOutput();

            int[] c = Nud.WriteMaterial(m, currentMaterialList, s);

            FileOutput fin = new FileOutput();

            fin.WriteInt(0);

            fin.WriteInt(20 + c[0]);
            for (int i = 1; i < 4; i++)
            {
                fin.WriteInt(c[i] == c[i - 1] ? 0 : 20 + c[i]);
            }

            for (int i = 0; i < 4 - c.Length; i++)
            {
                fin.WriteInt(0);
            }

            fin.WriteOutput(m);
            fin.Align(32, 0xFF);
            fin.WriteIntAt(fin.Size(), 0);
            fin.WriteOutput(s);
            fin.Save(fileName);
        }
示例#4
0
        public void ExportBntx(string filename)
        {
            FileOutput o = new FileOutput();

            o.endian = Endianness.Little;

            o.Save(filename);
        }
示例#5
0
        public override void Save()
        {
            FileOutput o = new FileOutput();

            byte[] n = lumen.Rebuild();
            o.WriteBytes(n);
            o.Save(lumen.Filename);
            Edited = false;
        }
示例#6
0
        public DRP(string fname)
        {
            Text = Path.GetFileNameWithoutExtension(fname);
            var o = new FileOutput();

            o.WriteBytes(Decrypt(new FileData(fname)));
            o.Save(fname + "_dec");
            Read(new FileData(Decrypt(new FileData(fname))));
        }
示例#7
0
        public void SaveAs(object sender, EventArgs args)
        {
            if (Runtime.TargetVbn == null)
            {
                MessageBox.Show("You must have a bone-set (VBN) selected to save animations.");
                return;
            }
            using (var sfd = new SaveFileDialog())
            {
                sfd.Filter = "Supported Files (.omo, .anim, .smd)|*.omo;*.anim;*.smd|" +
                             "Maya Anim (.anim)|*.anim|" +
                             "Object Motion (.omo)|*.omo|" +
                             "Source Animation (.smd)|*.smd|" +
                             "All Files (*.*)|*.*";

                sfd.DefaultExt = "smd"; //Set a default extension to prevent crashing if not specified by user
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    sfd.FileName = sfd.FileName;

                    if (sfd.FileName.EndsWith(".anim"))
                    {
                        if (Tag is AnimTrack)
                        {
                            ((AnimTrack)Tag).CreateAnim(sfd.FileName, Runtime.TargetVbn);
                        }
                        else
                        {
                            ANIM.CreateANIM(sfd.FileName, this, Runtime.TargetVbn);
                        }
                    }

                    if (sfd.FileName.EndsWith(".omo"))
                    {
                        if (Tag is FileData)
                        {
                            FileOutput o = new FileOutput();
                            o.WriteBytes(((FileData)Tag).GetSection(0,
                                                                    ((FileData)Tag).Size()));
                            o.Save(sfd.FileName);
                        }
                        else
                        {
                            File.WriteAllBytes(sfd.FileName, OMOOld.CreateOMOFromAnimation(this, Runtime.TargetVbn));
                        }
                    }


                    if (sfd.FileName.EndsWith(".smd"))
                    {
                        Smd.Save(this, Runtime.TargetVbn, sfd.FileName);
                    }
                }
            }
        }
示例#8
0
        public override void Save()
        {
            if (string.IsNullOrEmpty(FilePath))
            {
                SaveAs();
                return;
            }
            FileOutput o = new FileOutput();

            byte[] n = Swag.Rebuild();
            o.WriteBytes(n);
            o.Save(FilePath);
            Edited = false;
        }
示例#9
0
        public override void Save()
        {
            if (FilePath.Equals(""))
            {
                SaveAs();
                return;
            }
            FileOutput o = new FileOutput();

            byte[] n = mta.Rebuild();
            o.WriteBytes(n);
            o.Save(FilePath);
            Edited = false;
        }
示例#10
0
        public override void Save()
        {
            if (FilePath.Equals(""))
            {
                SaveAs();
                return;
            }
            FileOutput o = new FileOutput();

            mta.Compile(new List <string>(richTextBox1.Text.Split('\n')));
            byte[] n = mta.Rebuild();
            o.WriteBytes(n);
            o.Save(FilePath);
            Edited = false;
        }
示例#11
0
        // Writing

        public void Save(string fname)
        {
            FileOutput f = new FileOutput();

            f.endian = System.IO.Endianness.Big;

            // header
            FileOutput header = new FileOutput();

            header.endian = System.IO.Endianness.Big;

            FileOutput data = new FileOutput();

            data.endian = System.IO.Endianness.Big;


            f.Save(fname);
        }
示例#12
0
        private void saveNUTZLIBToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (var sfd = new SaveFileDialog())
            {
                sfd.Filter = "Namco Universal Texture (.nut)|*.nut|" +
                             "All Files (*.*)|*.*";

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    if (sfd.FileName.EndsWith(".nut") && currentNut != null)
                    {
                        FileOutput o = new FileOutput();
                        o.WriteBytes(FileData.DeflateZlib(currentNut.Rebuild()));
                        o.Save(sfd.FileName);
                    }
                }
            }
        }
示例#13
0
        public override void Save()
        {
            ShowGtxMipmapWarning(currentNut);

            if (FilePath.Equals(""))
            {
                SaveAs();
                return;
            }

            FileOutput fileOutput = new FileOutput();

            byte[] n = currentNut.Rebuild();

            fileOutput.WriteBytes(n);
            fileOutput.Save(FilePath);
            Edited = false;
        }
示例#14
0
                public void Play()
                {
                    // this cannot be very fast .-.
                    // if anyone know how to pass the file via a byte array then that would be great...
                    File.WriteAllBytes("temp.idsp", idsp);
                    Console.WriteLine("here");
                    IntPtr vgm = VGMStreamNative.InitVGMStream("temp.idsp");

                    if (vgm == IntPtr.Zero)
                    {
                        throw new Exception("Error loading idsp");
                    }

                    Console.WriteLine("here");
                    int channelCount = VGMStreamNative.GetVGMStreamChannelCount(vgm);
                    int bitsPerFrame = VGMStreamNative.GetVGMStreamFrameSize(vgm);
                    int size         = VGMStreamNative.GetVGMStreamTotalSamples(vgm);
                    int samplerate   = VGMStreamNative.GetVGMStreamSampleRate(vgm);

                    Console.WriteLine("here");

                    int total = (int)((samplerate * bitsPerFrame * channelCount * (size / 24576000f)) / 8 * 1024);

                    //Console.WriteLine(channelCount + " " + bitsPerFrame + " " + size + " " + samplerate + " " + total.ToString("x"));

                    short[] buffer = new short[total];

                    VGMStreamNative.RenderVGMStream(buffer, buffer.Length / 2, vgm);
                    Console.WriteLine("here");

                    FileOutput o = new FileOutput();

                    o.endian = Endianness.Little;
                    for (int i = 0; i < buffer.Length / 2; i++)
                    {
                        o.WriteShort(buffer[i]);
                    }
                    o.Save("test.wav");
                    Console.WriteLine("here");
                    WAVE.Play(o.GetBytes(), VGMStreamNative.GetVGMStreamChannelCount(vgm), VGMStreamNative.GetVGMStreamSamplesPerFrame(vgm), VGMStreamNative.GetVGMStreamSampleRate(vgm));

                    VGMStreamNative.CloseVGMStream(vgm);
                    File.Delete("temp.idsp");
                }
示例#15
0
        public void Save(string filename)
        {
            FileOutput f = new FileOutput();

            f.endian = System.IO.Endianness.Big;
            f.WriteChars("ATKD".ToCharArray());
            f.WriteInt(entries.Count);
            f.WriteUInt(commonSubactions);
            f.WriteUInt(uniqueSubactions);
            foreach (Entry e in entries)
            {
                f.WriteUShort(e.subaction);
                f.WriteUShort(0);
                f.WriteUShort(e.startFrame);
                f.WriteUShort(e.lastFrame);
                f.WriteFloat(e.xmin);
                f.WriteFloat(e.xmax);
                f.WriteFloat(e.ymin);
                f.WriteFloat(e.ymax);
            }
            f.Save(filename);
        }
示例#16
0
        public void Save(string fname)
        {
            FileOutput f = new FileOutput();

            f.endian = System.IO.Endianness.Little;

            f.WriteUInt(Magic);

            f.WriteUInt(header.size);
            f.WriteUInt(header.flags);
            f.WriteUInt(header.height);
            f.WriteUInt(header.width);
            f.WriteUInt(header.pitchOrLinearSize);
            f.WriteUInt(header.depth);
            f.WriteUInt(header.mipmapCount);
            for (int i = 0; i < 11; ++i)
            {
                f.WriteUInt(header.reserved1[i]);
            }

            f.WriteUInt(header.ddspf.size);
            f.WriteUInt(header.ddspf.flags);
            f.WriteUInt(header.ddspf.fourCc);
            f.WriteUInt(header.ddspf.rgbBitCount);
            f.WriteUInt(header.ddspf.rBitMask);
            f.WriteUInt(header.ddspf.gBitMask);
            f.WriteUInt(header.ddspf.bBitMask);
            f.WriteUInt(header.ddspf.aBitMask);

            f.WriteUInt(header.caps);
            f.WriteUInt(header.caps2);
            f.WriteUInt(header.caps3);
            f.WriteUInt(header.caps4);
            f.WriteUInt(header.reserved2);

            f.WriteBytes(bdata);

            f.Save(fname);
        }
示例#17
0
 private void extractRom(object sender, EventArgs e)
 {
     using (OpenFileDialog ofd = new OpenFileDialog())
     {
         ofd.Title = "Select NES ROM";
         if (ofd.ShowDialog() == DialogResult.OK)
         {
             using (SaveFileDialog sfd = new SaveFileDialog())
             {
                 sfd.Title = "Select Save Location";
                 if (sfd.ShowDialog() == DialogResult.OK)
                 {
                     byte[]     rom = File.ReadAllBytes(ofd.FileName);
                     FileOutput f   = new FileOutput();
                     for (int i = 0x30; i < rom.Length - 0x20; i++)
                     {
                         f.WriteByte(rom[i]);
                     }
                     f.Save(sfd.FileName);
                 }
             }
         }
     }
 }
示例#18
0
        public void SaveAsMBN(string fname)
        {
            int        format = 6;
            FileOutput o      = new FileOutput();

            o.endian = Endianness.Little;

            o.WriteShort(format);
            o.WriteShort(0xFFFF);
            o.WriteInt(0); //flags
            o.WriteInt(1); //mode
            o.WriteInt(Nodes.Count);

            // Write Vertex Attributes
            {
                o.WriteInt(attributes.Count);
                foreach (VertexAttribute va in attributes)
                {
                    o.WriteInt(va.type);
                    o.WriteInt(va.format);
                    o.WriteFloat(va.scale);
                }
            }


            //Vertex Buffer
            FileOutput vertexBuffer = new FileOutput();

            vertexBuffer.endian = Endianness.Little;

            for (int i = 0; i < vertices.Length; i++)
            {
                foreach (VertexAttribute va in attributes)
                {
                    //Write Data
                    va.WriteVertex(vertexBuffer, ref vertices[i]);
                }
            }

            o.WriteInt(vertexBuffer.Size()); // Vertex Buffer Size

            //Mesh Information
            FileOutput indexBuffer = new FileOutput();

            indexBuffer.endian = Endianness.Little;
            foreach (BCH_Mesh mesh in Nodes)
            {
                o.WriteInt(mesh.Nodes.Count);
                foreach (BCH_PolyGroup pg in mesh.Nodes)
                {
                    // Node List
                    o.WriteInt(pg.BoneList.Length);
                    foreach (int b in pg.BoneList)
                    {
                        o.WriteInt(b);
                    }

                    // Triangle Count
                    o.WriteInt(pg.Faces.Length);
                    // o.writeInt(0); something if format == 4

                    // Index Buffer
                    foreach (int i in pg.Faces)
                    {
                        indexBuffer.WriteShort(i);
                    }
                    indexBuffer.Align(0x20, 0xFF);
                }
            }

            if (format != 4)
            {
                o.Align(0x20, 0xFF);
            }

            o.WriteOutput(vertexBuffer);
            o.Align(0x20, 0xFF);
            o.WriteOutput(indexBuffer);
            o.Save(fname);
        }
示例#19
0
        public byte[] Rebuild(bool dump = false)
        {
            FileOutput o = new FileOutput();

            TextWriter   oldOut = Console.Out;
            MemoryStream ostrm  = new MemoryStream(0xA00000);
            StreamWriter writer = new StreamWriter(ostrm);

            Console.SetOut(writer);

            // TODO: write correct filesize in header.
            // It isn't checked by the game, but what the hell, right?
            header.Write(o);

            writeSymbols(o);
            writeColors(o);
            writeTransforms(o);
            writePositions(o);
            writeBounds(o);

            Actionscript.Write(o);
            if (Actionscript2 != null)
            {
                Actionscript2.Write(o);
            }

            writeAtlases(o);

            unkF008.Write(o);
            unkF009.Write(o);
            unkF00A.Write(o);
            unk000A.Write(o);
            unkF00B.Write(o);
            properties.Write(o);

            Defines.numShapes  = (uint)Shapes.Count;
            Defines.numSprites = (uint)Sprites.Count;
            Defines.numTexts   = (uint)Texts.Count;
            Defines.Write(o);

            writeShapes(o);
            writeSprites(o);
            writeTexts(o);

            o.WriteInt((int)TagType.End);
            o.WriteInt(0);

            int padSize = (4 - (o.Size() % 4)) % 4;

            for (int i = 0; i < padSize; i++)
            {
                o.WriteByte(0);
            }

            if (dump)
            {
                writer.Flush();
                using (var filestream = new FileStream("dump.txt", FileMode.Create))
                    ostrm.WriteTo(filestream);
            }

            Console.SetOut(oldOut);
            o.Save(Filename);
            return(o.GetBytes());
        }
示例#20
0
        public static void Rebuild(string fname, List <Animation> animations)
        {
            // poopity doo da
            // headery deadery
            FileOutput o = new FileOutput();

            o.WriteString("BCH");
            o.Align(4);
            o.WriteByte(0x21);    // version stuffs
            o.WriteByte(0x21);    // version stuffs
            o.endian = System.IO.Endianness.Little;
            o.WriteShort(0xA755); // version

            FileOutput d_Main = new FileOutput();

            d_Main.endian = System.IO.Endianness.Little;
            FileOutput d_Main2 = new FileOutput();

            d_Main2.endian = System.IO.Endianness.Little;
            FileOutput d_Main3 = new FileOutput();

            d_Main3.endian = System.IO.Endianness.Little;
            FileOutput d_String = new FileOutput();

            d_String.endian = System.IO.Endianness.Little;
            FileOutput d_GPU = new FileOutput();

            d_GPU.endian = System.IO.Endianness.Little;
            FileOutput d_Data = new FileOutput();

            d_Data.endian = System.IO.Endianness.Little;

            FileOutput Reloc = new FileOutput();

            Reloc.endian = System.IO.Endianness.Little;

            //Offsets
            o.WriteInt(0); //main
            o.WriteInt(0); //string
            o.WriteInt(0); //gpu
            o.WriteInt(0); //data
            o.WriteInt(0); //dataext
            o.WriteInt(0); //relocationtable

            //Length
            o.WriteInt(0);   //main
            o.WriteInt(0);   //string
            o.WriteInt(0);   //gpu
            o.WriteInt(0);   //data
            o.WriteInt(0);   //dataext
            o.WriteInt(0);   //relocationtable

            o.WriteInt(0);   //datasection
            o.WriteInt(0);   //

            o.WriteShort(1); //flag
            o.WriteShort(0); //addcount

            //Contents in the main header......

            d_Main.WriteInt(0);                                // Model
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // Material
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // Shader
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // Texture
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // MaterialLUT
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // Lights
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // Camera
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // Fog
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            // SkeAnim
            {
                // Names need to be in patricia tree.......
                Dictionary <string, int> NameBank = new Dictionary <string, int>();

                NameBank.Add("BustN", d_String.Size());
                d_String.WriteString("BustN");
                d_String.WriteByte(0);

                List <PatriciaTree.PatriciaTreeNode> Nodes = new List <PatriciaTree.PatriciaTreeNode>();
                int maxlength = 0;
                foreach (Animation a in animations)
                {
                    maxlength = Math.Max(maxlength, a.Text.Length);
                }

                Nodes.Add(new PatriciaTree.PatriciaTreeNode()
                {
                    ReferenceBit = uint.MaxValue
                });
                foreach (Animation a in animations)
                {
                    PatriciaTree.Insert(Nodes, new PatriciaTree.PatriciaTreeNode()
                    {
                        Name = a.Text
                    }, maxlength);
                }

                int nameOff = 0xb4 + d_Main2.Size();
                foreach (PatriciaTree.PatriciaTreeNode node in Nodes)
                {
                    d_Main2.WriteInt((int)node.ReferenceBit);
                    d_Main2.WriteShort(node.LeftNodeIndex);
                    d_Main2.WriteShort(node.RightNodeIndex);
                    if (node.Name.Equals(""))
                    {
                        d_Main2.WriteInt(0);
                    }
                    else
                    {
                        NameBank.Add(node.Name, d_String.Size());
                        d_Main2.WriteOffset(d_String.Size(), d_String);
                        d_String.WriteString(node.Name);
                        d_String.WriteByte(0);
                    }
                }
                // bones


                // Okay, first create the animation data then create the table pointng to it side by side

                int dataOff = 0xb4 + d_Main2.Size();
                foreach (Animation a in animations)
                {
                    d_Main2.WriteOffset(d_Main3.Size(), d_Main2);

                    // now create the actual animation data I guess
                    d_Main3.WriteOffset(NameBank[a.Text], d_String);   // name offset
                    d_Main3.WriteInt(0x2);                             // Flags TODO: What are these
                    d_Main3.WriteFloat(a.frameCount + 1);
                    d_Main3.WriteOffset(d_Main3.Size() + 12, d_Main3); // bone offset
                    d_Main3.WriteInt(a.bones.Count);                   // bonecount
                    d_Main3.WriteInt(0);                               // metadata nonsense

                    FileOutput boneHeader = new FileOutput();
                    boneHeader.endian = System.IO.Endianness.Little;
                    FileOutput keyData = new FileOutput();
                    keyData.endian = System.IO.Endianness.Little;
                    int start = d_Main3.Size() + (a.bones.Count * 4);
                    int track = 0;
                    foreach (Animation.KeyNode node in a.bones)
                    {
                        d_Main3.WriteOffset(start + boneHeader.Size(), d_Main3); // bone offset
                        // name type and flags
                        if (!NameBank.ContainsKey(node.Text))
                        {
                            NameBank.Add(node.Text, d_String.Size());
                            d_String.WriteString(node.Text);
                            d_String.WriteByte(0);
                        }
                        boneHeader.WriteOffset(NameBank[node.Text], d_String); // name offset
                        boneHeader.WriteInt(0x040000);                         // animation type flags, default is just simply transform
                        // Actual Flags
                        int flags = 0;
                        flags |= (((node.xsca.keys.Count > 0) ? 0 : 1) << (16 + 0));
                        flags |= (((node.ysca.keys.Count > 0) ? 0 : 1) << (16 + 1));
                        flags |= (((node.zsca.keys.Count > 0) ? 0 : 1) << (16 + 2));
                        flags |= (((node.xrot.keys.Count > 0) ? 0 : 1) << (16 + 3));
                        flags |= (((node.yrot.keys.Count > 0) ? 0 : 1) << (16 + 4));
                        flags |= (((node.zrot.keys.Count > 0) ? 0 : 1) << (16 + 5));
                        flags |= (((node.xpos.keys.Count > 0) ? 0 : 1) << (16 + 6));
                        flags |= (((node.ypos.keys.Count > 0) ? 0 : 1) << (16 + 7));
                        flags |= (((node.zpos.keys.Count > 0) ? 0 : 1) << (16 + 8));

                        flags |= (((node.xsca.keys.Count == 1) ? 1 : 0) << (6 + 0));
                        flags |= (((node.ysca.keys.Count == 1) ? 1 : 0) << (6 + 1));
                        flags |= (((node.zsca.keys.Count == 1) ? 1 : 0) << (6 + 2));
                        flags |= (((node.xrot.keys.Count == 1) ? 1 : 0) << (6 + 3));
                        flags |= (((node.yrot.keys.Count == 1) ? 1 : 0) << (6 + 4));
                        flags |= (((node.zrot.keys.Count == 1) ? 1 : 0) << (6 + 5));
                        flags |= (((node.xpos.keys.Count == 1) ? 1 : 0) << (6 + 7));
                        flags |= (((node.ypos.keys.Count == 1) ? 1 : 0) << (6 + 8));
                        flags |= (((node.zpos.keys.Count == 1) ? 1 : 0) << (6 + 9));
                        boneHeader.WriteInt(flags);

                        // Create KeyFrame Data
                        int sta = start + (a.bones.Count * 12 * 4);
                        WriteKeyData(node.xsca, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.ysca, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.zsca, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.xrot, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.yrot, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.zrot, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.xpos, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.ypos, boneHeader, keyData, d_Main3, sta, ref track);
                        WriteKeyData(node.zpos, boneHeader, keyData, d_Main3, sta, ref track);
                    }
                    d_Main3.WriteOutput(boneHeader);
                    d_Main3.WriteOutput(keyData);
                }

                d_Main.WriteOffset(dataOff, d_Main);
                d_Main.WriteInt(animations.Count);   //
                d_Main.WriteOffset(nameOff, d_Main); //
            }


            d_Main.WriteInt(0);                                // MaterialAnim
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // VisAnim
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // LightAnim
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // CameraAnim
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // FogAnim
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteInt(0);                                // Scene
            d_Main.WriteInt(0);                                //
            d_Main.WriteOffset(0xB4 + d_Main2.Size(), d_Main); //

            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);
            d_Main2.WriteInt(0);

            d_Main.WriteOutput(d_Main2);
            d_Main.WriteOutput(d_Main3);

            int headSize = o.Size();

            o.WriteIntAt(headSize, 0x08);
            o.WriteIntAt(d_Main.Size(), 0x20);
            o.WriteOutput(d_Main);
            o.Align(4);

            int stringSize = o.Size();

            o.WriteIntAt(stringSize, 0x0C);
            o.WriteIntAt(d_String.Size(), 0x24);
            o.WriteOutput(d_String);
            o.Align(4);

            int gpuSize = o.Size();

            o.WriteIntAt(d_GPU.Size() > 0 ? gpuSize : 0, 0x10);
            o.WriteIntAt(d_GPU.Size(), 0x28);
            o.WriteOutput(d_GPU);
            o.Align(0x100);

            int dataSize = o.Size();

            o.WriteIntAt(dataSize, 0x14);
            o.WriteIntAt(dataSize, 0x18);
            o.WriteIntAt(d_Data.Size(), 0x2C);
            o.WriteIntAt(d_Data.Size(), 0x30);
            o.WriteOutput(d_Data);

            //Create Relocation Table
            // Flag is 7 bits
            // 0 - main 1 - string 2 - gpu 3 - data
            foreach (FileOutput.RelocOffset off in o.offsets)
            {
                int size = 0;
                int code = 0;
                int div  = 4;
                if (off.output == d_Main || off.output == d_Main2 || off.output == d_Main3)
                {
                    size = headSize;
                    code = 0;
                    if (off.output == d_Main3)
                    {
                        off.value += headSize;
                    }
                    if (off.output == d_Main2)
                    {
                        off.value += d_Main2.Size() + headSize;
                    }
                }
                if (off.output == d_String)
                {
                    size = stringSize;
                    code = 1;
                    div  = 1;
                }
                if (off.output == d_GPU)
                {
                    size = gpuSize;
                    code = 2;
                }
                if (off.output == d_Data)
                {
                    size = dataSize;
                    code = 3;
                }

                o.WriteIntAt(off.value - size, off.position);
                int reloc = (code << 25) | (((off.position - headSize) / div) & 0x1FFFFFF);
                Reloc.WriteInt(reloc);
            }

            int relocSize = o.Size();

            o.WriteIntAt(relocSize, 0x1C);
            o.WriteIntAt(Reloc.Size(), 0x34);
            o.WriteOutput(Reloc);

            o.Save(fname);
        }