Ejemplo n.º 1
0
        public void Save(System.IO.Stream stream)
        {
            switch (FormatType)
            {
            case FileFormatType.BCH:
                H3D.Save(stream, H3DFile);
                break;

            default:
                throw new Exception($"File format cannot be saved yet! {FormatType}");
            }
        }
Ejemplo n.º 2
0
        public static void Save(H3D Scene, SceneState State)
        {
            if (Scene == null)
            {
                MessageBox.Show(
                    "Please load a file first!",
                    "No data",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);

                return;
            }

            using (SaveFileDialog SaveDlg = new SaveFileDialog())
            {
                SaveDlg.Filter =
                    "COLLADA 1.4.1|*.dae|" +
                    "Valve StudioMdl|*.smd|" +
                    "Binary Ctr H3D|*.bch|" +
                    "Material Script (Max)|*.ms|" +
                    "Material Dump|*.txt";

                //Offer to save using model name if possible
                if (State.ModelIndex > -1)
                {
                    SaveDlg.FileName = Scene.Models[State.ModelIndex].Name;
                }
                else
                {
                    SaveDlg.FileName = "Model";
                }

                if (SaveDlg.ShowDialog() == DialogResult.OK)
                {
                    int MdlIndex  = State.ModelIndex;
                    int AnimIndex = State.SklAnimIndex;

                    switch (SaveDlg.FilterIndex)
                    {
                    case 1: new DAE(Scene, MdlIndex, AnimIndex, Settings.Default.DebugCopyVtxAlpha).Save(SaveDlg.FileName); break;

                    case 2: new SMD(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 3: H3D.Save(SaveDlg.FileName, Scene); break;

                    case 4: new MaterialScript(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 5: new MaterialDump(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public static void Save(H3D Scene, SceneState State)
        {
            if (Scene == null)
            {
                MessageBox.Show(
                    "Please load a file first!",
                    "No data",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);

                return;
            }

            using (SaveFileDialog SaveDlg = new SaveFileDialog())
            {
                SaveDlg.Filter =
                    "COLLADA 1.4.1|*.dae" +
                    "|Valve StudioMdl|*.smd" +
                    "|Binary Ctr H3D|*.bch" +
                    "|Game Freak Model|*.gfbmdl";

                SaveDlg.FileName = "Model";

                if (SaveDlg.ShowDialog() == DialogResult.OK)
                {
                    int MdlIndex  = State.ModelIndex;
                    int AnimIndex = State.SklAnimIndex;

                    switch (SaveDlg.FilterIndex)
                    {
                    case 1: new DAE(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 2: new SMD(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 3: H3D.Save(SaveDlg.FileName, Scene); break;

                    case 4:
                        using (BinaryWriter writer = new BinaryWriter(new FileStream(SaveDlg.FileName, FileMode.Create, FileAccess.Write)))
                        {
                            new GFModel(Scene.Models[State.ModelIndex], Scene.LUTs).Write(writer);
                            writer.Close();
                        }
                        break;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        public static void Save(H3D Scene, SceneState State)
        {
            if (Scene == null)
            {
                MessageBox.Show(
                    "Please load a file first!",
                    "No data",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);

                return;
            }

            using (SaveFileDialog SaveDlg = new SaveFileDialog())
            {
                SaveDlg.Filter =
                    "COLLADA 1.4.1|*.dae|" +
                    "Valve StudioMdl|*.smd|" +
                    "Blender File|*.blend|" +
                    "Binary Ctr H3D|*.bch";

                SaveDlg.FileName = "Model";

                if (SaveDlg.ShowDialog() == DialogResult.OK)
                {
                    int MdlIndex  = State.ModelIndex;
                    int AnimIndex = State.SklAnimIndex;

                    switch (SaveDlg.FilterIndex)
                    {
                    case 1: new DAE(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 2: new SMD(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 3: new BLEND(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 4: H3D.Save(SaveDlg.FileName, Scene); break;
                    }
                }
            }
        }
Ejemplo n.º 5
0
        static void Main(string[] args)
        {
            List <string> argsList = new List <string>(args);

            if (args.Length > 0)
            {
                WorkMode mode = WorkMode.None;
                switch (args[0])
                {
                case "texturemerge":
                    mode = WorkMode.TextureMerge;
                    break;

                case "objconvert":
                    mode = WorkMode.OBJConvert;
                    break;

                case "cmif":
                    mode = WorkMode.CMIFConvert;
                    break;
                }
                if (mode != WorkMode.None)
                {
                    string input  = null;
                    string donor  = null;
                    string output = null;
                    if (argsList.Contains("-i"))
                    {
                        int index = argsList.IndexOf("-i") + 1;
                        if (index >= argsList.Count)
                        {
                            Console.WriteLine("Argument out of reach - input");
                            return;
                        }
                        else
                        {
                            input = args[index];
                        }
                    }

                    if (argsList.Contains("-d"))
                    {
                        int index = argsList.IndexOf("-d") + 1;
                        if (index >= argsList.Count)
                        {
                            Console.WriteLine("Argument out of reach - donor");
                            return;
                        }
                        else
                        {
                            donor = args[index];
                        }
                    }

                    if (argsList.Contains("-o"))
                    {
                        int index = argsList.IndexOf("-o") + 1;
                        if (index >= argsList.Count)
                        {
                            Console.WriteLine("Argument out of reach - output");
                            return;
                        }
                        else
                        {
                            output = args[index];
                        }
                    }

                    if (input == null)
                    {
                        Console.WriteLine("Input argument missing");
                        return;
                    }
                    if (mode == WorkMode.TextureMerge && donor == null)
                    {
                        Console.WriteLine("Texture merge donor argument missing");
                        return;
                    }

                    H3D Scene = new H3D();

                    if (donor != null)
                    {
                        using (FileStream FS = new FileStream(donor, FileMode.Open))
                        {
                            Console.WriteLine("Starting conversion");
                            if (FS.Length > 4)
                            {
                                BinaryReader Reader = new BinaryReader(FS);

                                uint MagicNum = Reader.ReadUInt32();

                                FS.Seek(-4, SeekOrigin.Current);

                                string Magic = Encoding.ASCII.GetString(Reader.ReadBytes(4));

                                FS.Seek(0, SeekOrigin.Begin);

                                if (Magic.StartsWith("BCH"))
                                {
                                    Console.WriteLine("Merging H3D " + donor);

                                    Scene = H3D.Open(Reader.ReadBytes((int)FS.Length));

                                    FS.Dispose();
                                }
                            }
                        }
                    }

                    string outFile = output;
                    if (outFile == null)
                    {
                        outFile = Path.GetFileNameWithoutExtension(input) + "_conv.bch";
                    }

                    switch (mode)
                    {
                    case WorkMode.OBJConvert:
                        Scene.Materials.Clear();
                        Scene.Models.Clear();
                        goto case WorkMode.TextureMerge;

                    case WorkMode.TextureMerge:
                    {
                        bool textureless = false;
                        if (argsList.Contains("-notextures"))
                        {
                            Console.WriteLine("No texture mode");
                            textureless = true;
                        }
                        Console.WriteLine("Merging OBJ " + input);

                        Scene.Merge(new OBJ(input).ToH3D(Directory.GetParent(input).FullName, textureless));
                    }
                    break;

                    case WorkMode.CMIFConvert:
                    {
                        Console.WriteLine("Converting Common Interchange file to H3D...");

                        Scene.Merge(new CMIFFile(new FileStream(input, FileMode.Open)).ToH3D());
                    }
                    break;
                    }



                    H3D.Save(outFile, Scene);

                    Console.WriteLine("Saved as " + outFile);
                }
            }
            else
            {
                printHelp();
            }
        }
Ejemplo n.º 6
0
        static void Main(string[] args)
        {
            ArgumentBuilder ab = new ArgumentBuilder(
                new ArgumentPattern("input", "One or more converter input files", ArgumentType.STRING, null, true, "-i"),
                new ArgumentPattern("output", "An optional specified output file.", ArgumentType.STRING, null, "-o"),
                new ArgumentPattern("outputType", "The output format type (h3d/gfmbdlp/gfx)", ArgumentType.STRING, "h3d", "-t", "--type"),
                new ArgumentPattern("outputVersion", "The output format version", ArgumentType.INT, (int)0x21, "-v", "--version"),
                new ArgumentPattern("filter", "Output format filters (model/texture/animation/all)", ArgumentType.STRING, "all", true, "-f", "--filter")
                );

            Console.WriteLine("SPICA Embedded Command Line Interface\n");
            ab.parse(args);

            ArgumentContent inputs = ab.getContent("input");

            if (inputs.contents.Count == 0)
            {
                Console.WriteLine("No inputs given. Stopping.\n");

                printHelp(ab);
            }
            else
            {
                string formatName = ab.getContent("outputType").stringValue();
                string formatExtension;
                switch (formatName)
                {
                case "h3d":
                    formatExtension = "bch";
                    break;

                case "gfbmdlp":
                    formatExtension = formatName;
                    break;

                case "gfx":
                    formatExtension = "bcres";
                    break;

                default:
                    Console.WriteLine("Unknown output type: " + formatName);
                    return;
                }

                H3D Scene = new H3D();

                Scene.BackwardCompatibility = (byte)ab.getContent("outputVersion").intValue();
                Scene.ForwardCompatibility  = Scene.BackwardCompatibility;

                for (int i = 0; i < inputs.contents.Count; i++)
                {
                    string inPath = inputs.stringValue(i);
                    if (File.Exists(inPath))
                    {
                        Scene.Merge(FormatIdentifier.IdentifyAndOpen(inPath));
                    }
                }

                ArgumentContent flt = ab.getContent("filter");

                bool deleteModel = true;
                bool deleteTex   = true;
                bool deleteAnime = true;

                for (int i = 0; i < flt.contents.Count; i++)
                {
                    string filter = flt.stringValue(i);
                    switch (filter)
                    {
                    case "model":
                        deleteModel = false;
                        break;

                    case "texture":
                        deleteModel = false;
                        break;

                    case "animation":
                        deleteAnime = false;
                        break;

                    case "all":
                        deleteAnime = false;
                        deleteModel = false;
                        deleteTex   = false;
                        break;

                    default:
                        Console.WriteLine("Warning: unknown filter - " + filter);
                        break;
                    }
                }

                if (deleteModel)
                {
                    Scene.Models.Clear();
                }
                if (deleteTex)
                {
                    Scene.Textures.Clear();
                }
                if (deleteAnime)
                {
                    Scene.MaterialAnimations.Clear();
                    Scene.SkeletalAnimations.Clear();
                    Scene.VisibilityAnimations.Clear();
                    Scene.FogAnimations.Clear();
                    Scene.CameraAnimations.Clear();
                    Scene.LightAnimations.Clear();
                }

                string          outputFilePath = Path.Combine(Directory.GetParent(inputs.stringValue(0)).FullName, Path.GetFileNameWithoutExtension(inputs.stringValue(0)) + "." + formatExtension);
                ArgumentContent outCnt         = ab.getContent("output", true);
                if (outCnt != null)
                {
                    outputFilePath = outCnt.stringValue();
                }

                switch (formatName)
                {
                case "h3d":
                    H3D.Save(outputFilePath, Scene);
                    break;

                case "gfbmdlp":
                    using (BinaryWriter Writer = new BinaryWriter(new FileStream(outputFilePath, FileMode.Create, FileAccess.Write)))
                    {
                        GFModelPack ModelPack = new GFModelPack(Scene);
                        ModelPack.Write(Writer);
                        Writer.Close();
                    }
                    break;

                case "gfx":
                    Gfx.Save(outputFilePath, new Gfx(Scene));
                    break;
                }
            }
        }
Ejemplo n.º 7
0
        private void Open(string infile)
        {
            FileAttributes fileAttributes = File.GetAttributes(infile);

            if (fileAttributes.HasFlag(FileAttributes.Directory))
            {
                if (ModifierKeys == Keys.Control)
                {
                    AddLine(richTextBox1, $"Building Arc from {Path.GetFileName(infile)}...");
                    FEArc.PackArc(infile, Alignment, enablePaddingToolStripMenuItem.Checked);
                    AddLine(richTextBox1, "Done");
                }
                else if (ModifierKeys == Keys.Shift)
                {
                    AddLine(richTextBox1, $"Building BCH from {Path.GetFileName(infile)}...");

                    if (infile.EndsWith("_"))
                    {
                        infile = infile.Substring(0, infile.Length - "_".Length);
                    }

                    if (File.Exists(infile + ".bch"))
                    {
                        File.Delete(infile + ".bch");
                    }

                    List <string> files = Directory.GetFiles(infile, "*.*", SearchOption.AllDirectories).ToList();
                    H3D           Scene = new H3D();
                    Scene.ConverterVersion      = 44139;
                    Scene.BackwardCompatibility = 34;
                    Scene.ForwardCompatibility  = 35;
                    foreach (string file in files)
                    {
                        Bitmap texture;
                        try
                        {
                            texture = (Bitmap)Bitmap.FromFile(file);
                        }
                        catch (OutOfMemoryException)
                        {
                            Console.WriteLine("invalid image format, skipping");
                            continue;
                        }
                        Scene.Textures.Add(new H3DTexture(Path.GetFileNameWithoutExtension(file), texture, SPICA.PICA.Commands.PICATextureFormat.RGBA8));
                    }

                    if (Scene.Textures.Count <= 0)
                    {
                        AddLine(richTextBox1, "Error");
                        AddLine(richTextBox1, $"No images found in {Path.GetFileName(infile)}");
                    }
                    else
                    {
                        H3D.Save($"{infile}.bch", Scene);
                        AddLine(richTextBox1, "Done");
                    }
                    return;
                }
                else if (ModifierKeys == Keys.Alt)
                {
                    AddLine(richTextBox1, $"Building CTPK from {Path.GetFileName(infile)}...");
                    CTPK.MakeCTPK(infile);
                    AddLine(richTextBox1, "Done");
                }
                else
                {
                    foreach (string p in (new DirectoryInfo(infile)).GetFiles().Select(f => f.FullName))
                    {
                        Open(p);
                    }
                    foreach (string p in (new DirectoryInfo(infile)).GetDirectories().Select(f => f.FullName))
                    {
                        Open(p);
                    }
                }
            }
            else
            {
                byte[] data    = File.ReadAllBytes(infile);
                string magic   = FEIO.GetMagic(data);
                string ext     = Path.GetExtension(infile);
                string outpath = ext.Length == 0 ? infile : infile.Replace(ext, "");

                if (ModifierKeys == Keys.Control || batchCompressToolStripMenuItem.Checked) // Compression Method
                {
                    byte[] cmp;
                    if (lZ10CompressionToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Compressing {Path.GetFileName(infile)} to {Path.GetFileName(infile)}.lz using lz10...");
                        try
                        {
                            cmp = FEIO.LZ10Compress(data);
                        }
                        catch (Exception ex)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Compress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile + ".lz", cmp);
                        AddLine(richTextBox1, "Done");
                    }
                    else if (lZ11ToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Compressing {Path.GetFileName(infile)} to {Path.GetFileName(infile)}.lz using lz11...");
                        try
                        {
                            cmp = FEIO.LZ11Compress(data);
                        }
                        catch (Exception ex)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Compress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile + ".lz", cmp);
                        AddLine(richTextBox1, "Done");
                    }
                    else if (lZ13ToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Compressing {Path.GetFileName(infile)} to {Path.GetFileName(infile)}.lz using lz13...");
                        try
                        {
                            cmp = FEIO.LZ13Compress(data);
                        }
                        catch (Exception ex)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Compress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile + ".lz", cmp);
                        AddLine(richTextBox1, "Done");
                    }
                    else
                    {
                        AddLine(richTextBox1, "No Compression Method Selected, How did this even happen?");
                    }
                }
                else if (ext == ".lz" || magic == "Yaz0" || ext == ".cms" || ext == ".cmp") // Decompress Method
                {
                    byte[] dcmp;
                    if (data[0] == 0x10)
                    {
                        AddLine(richTextBox1, $"Decompressing {Path.GetFileName(infile)} using lz10...");
                        try
                        {
                            dcmp = FEIO.LZ10Decompress(data);
                        }
                        catch (Exception e)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Decompress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile.Replace(".lz", ""), dcmp);
                        AddLine(richTextBox1, "Done");
                    } //LZ10
                    else if (data[0] == 0x11)
                    {
                        AddLine(richTextBox1, $"Decompressing {Path.GetFileName(infile)} using lz11...");
                        try
                        {
                            dcmp = FEIO.LZ11Decompress(data);
                        }
                        catch (Exception e)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Decompress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile.Replace(".lz", ""), dcmp);
                        AddLine(richTextBox1, "Done");
                    } //LZ11
                    else if (data[0] == 0x13 && data[4] == 0x11)
                    {
                        AddLine(richTextBox1, $"Decompressing {Path.GetFileName(infile)} using lz13...");
                        try
                        {
                            dcmp = FEIO.LZ13Decompress(data);
                        }
                        catch (Exception e)
                        {
                            AddLine(richTextBox1, $"\nUnable to automatically Decompress {Path.GetFileName(infile)}");
                            return;
                        }
                        File.WriteAllBytes(infile.Replace(".lz", ""), dcmp);
                        AddLine(richTextBox1, "Done");
                    } //LZ13
                    else if (magic == "Yaz0")
                    {
                        AddLine(richTextBox1, "Yaz0 Method not implemented");
                        return;
                    } //Yaz0
                    if (File.Exists(infile.Replace(".lz", "")) && autoExtractToolStripMenuItem.Checked)
                    {
                        Open(infile.Replace(".lz", ""));
                    }
                }
                else if (ext == ".arc") //Archive file
                {
                    AddLine(richTextBox1, $"Extract Files from {Path.GetFileName(infile)}...");
                    FEArc.ExtractArc(outpath, data);
                    AddLine(richTextBox1, "Done");
                }
                else if (magic == "BCH" || magic == "CGFX") //BCH / Bcres file
                {
                    H3D Scene = new H3D();
                    if (magic == "CGFX")
                    {
                        Scene = Gfx.Open(infile).ToH3D();
                    }
                    else
                    {
                        Scene = H3D.Open(data);
                    }

                    if (Directory.Exists(outpath))
                    {
                        Directory.Delete(outpath, true);
                    }
                    if (File.Exists(outpath))
                    {
                        outpath = outpath + "_";
                    }

                    //Export method for textures, this is always enabled by default
                    if (Scene.Textures.Count > 0)
                    {
                        AddLine(richTextBox1, $"Extracting Textures from {Path.GetFileName(infile)}...");
                        if (!Directory.Exists(outpath))
                        {
                            Directory.CreateDirectory(outpath);
                        }

                        foreach (var texture in Scene.Textures)
                        {
                            Image img = texture.ToBitmap();
                            img.Save($"{outpath}\\{texture.Name}.png", System.Drawing.Imaging.ImageFormat.Png);
                        }
                        AddLine(richTextBox1, "Done");
                    }
                    if (exportDaeToolStripMenuItem.Checked || exportSMDToolStripMenuItem.Checked && Scene.Models.Count > 0)
                    {
                        AddLine(richTextBox1, $"Extracting Models from {Path.GetFileName(infile)}...");
                        if (!Directory.Exists(outpath))
                        {
                            Directory.CreateDirectory(outpath);
                        }

                        for (int i = 0; i < Scene.Models.Count; i++)
                        {
                            if (exportDaeToolStripMenuItem.Checked)
                            {
                                DAE dae = new DAE(Scene, i);
                                dae.Save($"{outpath}\\{Scene.Models[i].Name}.dae");
                            }
                            if (exportSMDToolStripMenuItem.Checked)
                            {
                                SMD smd = new SMD(Scene, i);
                                smd.Save($"{outpath}\\{Scene.Models[i].Name}.smd");
                            }
                        }
                        AddLine(richTextBox1, "Done");
                    }
                }
                else if (magic == "CTPK") //CTPK file
                {
                    AddLine(richTextBox1, $"Extract Textures from {Path.GetFileName(infile)}...");
                    CTPK.ExtractCTPK(infile);
                    AddLine(richTextBox1, "Done");
                }
                else if (ext == ".bin")
                {
                    if (FEIO.ReadStringFromArray(data, Encoding.UTF8, 0x20).Contains("MESS_ARCHIVE"))
                    {
                        AddLine(richTextBox1, $"Extracting Message Archive {Path.GetFileName(infile)}...");
                        FEMessage.ExtractMessage(infile.Replace(ext, ".txt"), data);
                        AddLine(richTextBox1, "Done");
                    }
                    else if (enableBinDecomplingToolStripMenuItem.Checked)
                    {
                        AddLine(richTextBox1, $"Decompiling {Path.GetFileName(infile)} to txt...");
                        FEBin.ExtractBin(infile);
                        AddLine(richTextBox1, "Done");
                    }
                }
                if (deleteAfterProcessingToolStripMenuItem.Checked)
                {
                    File.Delete(infile);
                }
            }
        }
Ejemplo n.º 8
0
        public static void Save(H3D Scene, SceneState State)
        {
            if (Scene == null)
            {
                MessageBox.Show(
                    "Please load a file first!",
                    "No data",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);

                return;
            }

            using (SaveFileDialog SaveDlg = new SaveFileDialog())
            {
                SaveDlg.Filter =
                    "COLLADA 1.4.1|*.dae" +
                    "|Valve StudioMdl|*.smd" +
                    "|Binary Ctr H3D v33|*.bch" +
                    "|Binary Ctr H3D v7|*.bch" +
                    /* "|Game Freak Binary Model Pack|*.gfbmdlp" +*/
                    "|Binary CTR Resource|*.bcres"// +
                    /*"|Game Freak Binary Model|*.gfbmdl"*/
                ;

                SaveDlg.FileName = "Model";
                if (Scene.Models.Count > 0)
                {
                    SaveDlg.FileName = Scene.Models[0].Name;
                }

                if (SaveDlg.ShowDialog() == DialogResult.OK)
                {
                    int MdlIndex  = State.ModelIndex;
                    int AnimIndex = State.SklAnimIndex;

                    switch (SaveDlg.FilterIndex)
                    {
                    case 1: new DAE(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 2: new SMD(Scene, MdlIndex, AnimIndex).Save(SaveDlg.FileName); break;

                    case 3:
                        Scene.BackwardCompatibility = 0x21;
                        Scene.ForwardCompatibility  = 0x21;
                        H3D.Save(SaveDlg.FileName, Scene);
                        break;

                    case 4:
                        Scene.BackwardCompatibility = 0x7;
                        Scene.ForwardCompatibility  = 0x7;
                        H3D.Save(SaveDlg.FileName, Scene);
                        break;

                    case 5:
                        Gfx GFX = new Gfx(Scene);
                        Gfx.Save(SaveDlg.FileName, GFX);
                        break;

                    case 6:
                        MessageBox.Show(
                            "GFBMDLP writing comes with no warranty whatsoever. In fact, character and Pokémon models will most certainly not work at all.\n\n(Before you ask, this dialog can not be disabled. Intentionally.)",
                            "Disclaimer",
                            MessageBoxButtons.OK,
                            MessageBoxIcon.Exclamation);
                        using (BinaryWriter Writer = new BinaryWriter(new FileStream(SaveDlg.FileName, FileMode.Create, FileAccess.Write)))
                        {
                            GFModelPack ModelPack = new GFModelPack(Scene);
                            ModelPack.Write(Writer);
                            Writer.Close();
                        }
                        break;

                    case 7:
                        if (State.ModelIndex != -1)
                        {
                            H3DModel Model = Scene.Models[State.ModelIndex];

                            using (BinaryWriter Writer = new BinaryWriter(new FileStream(SaveDlg.FileName, FileMode.Create, FileAccess.Write)))
                            {
                                GFModel Mdl = new GFModel(Model, Scene.LUTs);
                                Mdl.Write(Writer);
                            }
                        }
                        else
                        {
                            MessageBox.Show(
                                "Please select a model to export.",
                                "No model selected",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);
                        }
                        break;
                    }
                }
            }
        }