OSDN Git Service

rename TSONode#name to path.
[tdcgexplorer/tso2mqo.git] / Form1.cs
index 44fd91e..133f92d 100644 (file)
--- a/Form1.cs
+++ b/Form1.cs
-using System;\r
-using System.Collections.Generic;\r
-using System.ComponentModel;\r
-using System.Data;\r
-using System.Drawing;\r
-using System.IO;\r
-using System.Text;\r
-using System.Windows.Forms;\r
-using Microsoft.Win32;\r
-\r
-namespace Tso2MqoGui\r
-{\r
-    public partial class Form1 : Form\r
-    {\r
-        public string   OutPath\r
-        {\r
-            get { return tbPath.Text; }\r
-            set { tbPath.Text= value; }\r
-        }\r
-\r
-        public Form1()\r
-        {\r
-            InitializeComponent();\r
-        }\r
-\r
-        private void Form1_Load(object sender, EventArgs e)\r
-        {\r
-            RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");\r
-            OutPath = (string)reg.GetValue("OutPath", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));\r
-            tabControl1.SelectedIndex = (int)reg.GetValue("TabPage", 0);\r
-            tbMqoIn.Text = (string)reg.GetValue("MqoIn", "");\r
-            tbTso.Text = (string)reg.GetValue("Tso", "");\r
-            tbTsoEx.Text = (string)reg.GetValue("TsoEx", "");\r
-            tbMergeTso.Text = (string)reg.GetValue("MergeTso", "");\r
-            rbRefBone.Checked = (int)reg.GetValue("RefBone", 1) == 1;\r
-            rbOneBone.Checked = (int)reg.GetValue("OneBone", 0) == 1;\r
-            rbBoneNone.Checked = (int)reg.GetValue("BoneNone", 1) == 1;\r
-            rbBoneRokDeBone.Checked = (int)reg.GetValue("BoneRokDeBone", 0) == 1;\r
-            cbMakeSub.Checked = (int)reg.GetValue("MakeSub", 1) == 1;\r
-            cbCopyTSO.Checked = (int)reg.GetValue("CopyTSO", 1) == 1;\r
-            cbShowMaterials.Checked = (int)reg.GetValue("ShowMaterials", 0) == 1;\r
-\r
-            reg             = Application.UserAppDataRegistry.CreateSubKey("Form1");\r
-            Bounds          = new Rectangle(\r
-                (int)reg.GetValue("Left",     0),\r
-                (int)reg.GetValue("Top",      0),\r
-                (int)reg.GetValue("Width",  640),\r
-                (int)reg.GetValue("Height", 320));\r
-\r
-            EnableControlStuff();\r
-\r
-            Config  config  = Config.Instance;\r
-        }\r
-\r
-        private void Form1_FormClosed(object sender, FormClosedEventArgs e)\r
-        {\r
-            RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");\r
-            reg.SetValue("OutPath", OutPath);\r
-            reg.SetValue("TabPage", tabControl1.SelectedIndex);\r
-            reg.SetValue("MqoIn", tbMqoIn.Text);\r
-            reg.SetValue("Tso", tbTso.Text);\r
-            reg.SetValue("TsoEx", tbTsoEx.Text);\r
-            reg.SetValue("MergeTso", tbMergeTso.Text);\r
-            reg.SetValue("RefBone", rbRefBone.Checked ? 1 : 0);\r
-            reg.SetValue("OneBone", rbOneBone.Checked ? 1 : 0);\r
-            reg.SetValue("BoneNone", rbBoneNone.Checked ? 1 : 0);\r
-            reg.SetValue("BoneRokDeBone", rbBoneRokDeBone.Checked ? 1 : 0);\r
-            reg.SetValue("MakeSub", cbMakeSub.Checked ? 1 : 0);\r
-            reg.SetValue("CopyTSO", cbCopyTSO.Checked ? 1 : 0);\r
-            reg.SetValue("ShowMaterials", cbShowMaterials.Checked ? 1 : 0);\r
-\r
-            reg= Application.UserAppDataRegistry.CreateSubKey("Form1");\r
-\r
-            if((this.WindowState & FormWindowState.Minimized) == FormWindowState.Minimized)\r
-            {\r
-                reg.SetValue("Top",    RestoreBounds.Top);\r
-                reg.SetValue("Left",   RestoreBounds.Left);\r
-                reg.SetValue("Width",  RestoreBounds.Width);\r
-                reg.SetValue("Height", RestoreBounds.Height);\r
-            } else\r
-            {\r
-                reg.SetValue("Top",    Top);\r
-                reg.SetValue("Left",   Left);\r
-                reg.SetValue("Width",  Width);\r
-                reg.SetValue("Height", Height);\r
-            }\r
-\r
-            Config.Save();\r
-        }\r
-\r
-        private void Form1_DragDrop(object sender, DragEventArgs e)\r
-        {\r
-            try\r
-            {\r
-                if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
-                    return;\r
-\r
-                string[]    files   = (string[])e.Data.GetData(DataFormats.FileDrop);\r
-\r
-                if(files.Length == 0)\r
-                    return;\r
-\r
-                switch(tabControl1.SelectedIndex)\r
-                {\r
-                case 0:\r
-                    foreach(string i in files)\r
-                    {\r
-                        if(Path.GetExtension(i).ToUpper() == ".TSO")\r
-                            OpenTSOFile(i);\r
-                    }\r
-\r
-                    break;\r
-\r
-                case 1:\r
-                    switch (Path.GetExtension(files[0]).ToUpper())\r
-                    {\r
-                        case ".TSO": tbTso.Text = files[0]; break;\r
-                        case ".MQO": tbMqoIn.Text = files[0]; break;\r
-                    }\r
-\r
-                    break;\r
-\r
-                case 2:\r
-                    AddMergeTso(files);\r
-                    break;\r
-                }\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-        }\r
-\r
-        private void Form1_DragEnter(object sender, DragEventArgs e)\r
-        {\r
-            if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
-                return;\r
-\r
-            e.Effect    = DragDropEffects.Copy;\r
-        }\r
-\r
-        private void tbMergeTso_DragDrop(object sender, DragEventArgs e)\r
-        {\r
-            if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
-                return;\r
-\r
-            string[]    files   = (string[])e.Data.GetData(DataFormats.FileDrop);\r
-\r
-            switch(Path.GetExtension(files[0]).ToUpper())\r
-            {\r
-            case ".TSO":    tbMergeTso.Text= files[0];  break;\r
-            }\r
-        }\r
-\r
-        private void tbMergeTso_DragEnter(object sender, DragEventArgs e)\r
-        {\r
-            if(!e.Data.GetDataPresent(DataFormats.FileDrop))\r
-                return;\r
-\r
-            e.Effect    = DragDropEffects.Copy;\r
-        }\r
-\r
-        private void OpenTSOFile(string f)\r
-        {\r
-            string  dir = OutPath;\r
-\r
-            if(cbMakeSub.Checked)\r
-            {\r
-                dir = Path.Combine(dir, Path.GetFileNameWithoutExtension(f));\r
-\r
-                if(!Directory.Exists(dir))\r
-                    Directory.CreateDirectory(dir);\r
-            }\r
-\r
-            string      file= Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(f), ".mqo"));\r
-            string      info= Path.Combine(dir, Path.ChangeExtension(Path.GetFileName(f), ".xml"));\r
-\r
-            try\r
-            {\r
-                label2.BackColor= Color.Tomato;\r
-                label2.ForeColor= Color.White;\r
-                label2.Text     = "Processing";\r
-                label2.Invalidate();\r
-                label2.Update();\r
-\r
-                // モデル、テクスチャの作成\r
-                using(MqoWriter mqo = new MqoWriter(file))\r
-                {\r
-                    TSOFile     tso = new TSOFile(f);\r
-                    tso.ReadAll();\r
-\r
-                    if(rbBoneRokDeBone.Checked) mqo.BoneMode    = MqoBoneMode.RokDeBone;\r
-\r
-                    mqo.Write(tso);\r
-                    mqo.Close();\r
-\r
-                    ImportInfo  ii  = new ImportInfo();\r
-\r
-                    // テクスチャ情報\r
-                    foreach(TSOTex i in tso.textures)\r
-                        ii.textures.Add(new ImportTextureInfo(i));\r
-\r
-                    // エフェクトの作成\r
-                    foreach(TSOEffect i in tso.effects)\r
-                    {\r
-                        ii.effects.Add(new ImportEffectInfo(i));\r
-                        File.WriteAllText(Path.Combine(dir, i.Name), i.code, Encoding.Default);\r
-                    }\r
-\r
-                    // マテリアルの作成\r
-                    foreach(TSOMaterial i in tso.materials)\r
-                    {\r
-                        ii.materials.Add(new ImportMaterialInfo(i));\r
-                        File.WriteAllText(Path.Combine(dir, i.Name), i.code, Encoding.Default);\r
-                      //File.WriteAllText(Path.Combine(dir, i.File), i.code, Encoding.Default);\r
-                    }\r
-\r
-                    ImportInfo.Save(info, ii);\r
-                }\r
-\r
-                if(cbCopyTSO.Checked)\r
-                {\r
-                    file    = Path.Combine(dir, Path.GetFileName(f));\r
-\r
-                    if(f != file)\r
-                        File.Copy(f, file, true);\r
-                }\r
-            } finally\r
-            {\r
-                label2.BackColor    = SystemColors.Control;\r
-                label2.BackColor    = label2.Parent.BackColor;\r
-                label2.ForeColor    = SystemColors.ControlText;\r
-                label2.Text         = "Drop TSO File Here!";\r
-            }\r
-\r
-          //System.Diagnostics.Process.Start(file);\r
-        }\r
-\r
-        private void OpenMQOFile(string f)\r
-        {\r
-            TSOGenerator gen = new TSOGenerator();\r
-            TSOGenerateConfig config = new TSOGenerateConfig();\r
-            config.ShowMaterials = cbShowMaterials.Checked;\r
-\r
-            if (rbRefBone.Checked)\r
-            {\r
-                gen.GenerateRefBone(f, tbTso.Text, tbTsoEx.Text, config);\r
-            }\r
-            else\r
-            if (rbOneBone.Checked)\r
-            {\r
-                Dictionary<string, string> boneref = new Dictionary<string, string>();\r
-\r
-                foreach (ListViewItem i in lvObject.Items)\r
-                {\r
-                    if (i.SubItems[1].Text == "")\r
-                    {\r
-                        MessageBox.Show("すべてのオブジェクトにボーンを設定してください");\r
-                        return;\r
-                    }\r
-\r
-                    boneref.Add(i.SubItems[0].Text, i.SubItems[1].Text);\r
-                }\r
-\r
-                gen.GenerateOneBone(f, tbTso.Text, tbTsoEx.Text, config, boneref);\r
-            }\r
-            else\r
-            {\r
-            }\r
-        }\r
-#region tso->mqo UI\r
-        private void button1_Click(object sender, EventArgs e)\r
-        {\r
-            FolderBrowserDialog dlg = new FolderBrowserDialog();\r
-            dlg.SelectedPath    = OutPath;\r
-\r
-            if(dlg.ShowDialog() == DialogResult.OK)\r
-                OutPath = dlg.SelectedPath;\r
-        }\r
-#endregion\r
-#region mqo->tso UI\r
-        private void radioButton1_CheckedChanged(object sender, EventArgs e)\r
-        {\r
-            EnableControlStuff();\r
-        }\r
-\r
-        private void radioButton2_CheckedChanged(object sender, EventArgs e)\r
-        {\r
-            EnableControlStuff();\r
-        }\r
-\r
-        private void EnableControlStuff()\r
-        {\r
-            gbBone.Enabled  = rbOneBone.Checked;\r
-        }\r
-\r
-        private void BuildBoneTree(TreeNodeCollection nodes, TSONode node)\r
-        {\r
-            TreeNode    tn  = nodes.Add(node.ShortName);\r
-            tn.Tag          = node;\r
-\r
-            if(node.children != null)\r
-            foreach(TSONode i in node.children)\r
-                BuildBoneTree(tn.Nodes, i);\r
-        }\r
-\r
-        private void SaveAssign()\r
-        {\r
-            foreach(ListViewItem i in lvObject.Items)\r
-            {\r
-                string  obj = i.SubItems[0].Text;\r
-                string  bone= i.SubItems[1].Text;\r
-\r
-                if(Config.Instance.object_bone_map.ContainsKey(obj))\r
-                        Config.Instance.object_bone_map[obj]    = bone;\r
-                else    Config.Instance.object_bone_map.Add(obj, bone);\r
-            }\r
-        }\r
-\r
-        private void bRefMqoIn_Click(object sender, EventArgs e)\r
-        {\r
-            try\r
-            {\r
-                OpenFileDialog  dlg = new OpenFileDialog();\r
-                dlg.Filter  = "Metasequoia File(*.mqo)|*.mqo";\r
-                dlg.FileName= tbMqoIn.Text;\r
-\r
-                if(dlg.ShowDialog() == DialogResult.OK)\r
-                    tbMqoIn.Text    = dlg.FileName;\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-        }\r
-\r
-        private void bRefTso_Click(object sender, EventArgs e)\r
-        {\r
-            try\r
-            {\r
-                OpenFileDialog  dlg = new OpenFileDialog();\r
-                dlg.Filter  = "TSO File(*.tso)|*.tso";\r
-                dlg.FileName= tbTso.Text;\r
-\r
-                if(dlg.ShowDialog() == DialogResult.OK)\r
-                    tbTso.Text      = dlg.FileName;\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-        }\r
-\r
-        private void bRefTsoEx_Click(object sender, EventArgs e)\r
-        {\r
-            try\r
-            {\r
-                SaveFileDialog  dlg = new SaveFileDialog();\r
-                dlg.Filter  = "TSO File(*.tso)|*.tso";\r
-                dlg.FileName= tbTsoEx.Text;\r
-\r
-                if(dlg.ShowDialog() == DialogResult.OK)\r
-                    tbTsoEx.Text    = dlg.FileName;\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-        }\r
-\r
-        private void bRefresh_Click(object sender, EventArgs e)\r
-        {\r
-            try\r
-            {\r
-                // 一旦現状を保存\r
-                SaveAssign();\r
-\r
-                // オブジェクト\r
-                MqoFile mqo = new MqoFile();\r
-                mqo.Load(tbMqoIn.Text);\r
-                lvObject.Items.Clear();\r
-\r
-                foreach(MqoObject i in mqo.Objects)\r
-                {\r
-                    ListViewItem    item= lvObject.Items.Add(i.name);\r
-                    item.Tag            = i;\r
-                    string          bone;\r
-\r
-                    if(Config.Instance.object_bone_map.TryGetValue(i.name, out bone))\r
-                            item.SubItems.Add(bone);\r
-                    else    item.SubItems.Add("");\r
-                }\r
-\r
-                // ボーン構造\r
-                TSOFile tso = new TSOFile(tbTso.Text);\r
-                tso.ReadAll();\r
-                tvBone.Visible  = false;\r
-                tvBone.Nodes.Clear();\r
-                BuildBoneTree(tvBone.Nodes, tso.nodes[0]);\r
-                tvBone.ExpandAll();\r
-                tvBone.Nodes[0].EnsureVisible();\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            } finally\r
-            {\r
-                tvBone.Visible  = true;\r
-            }\r
-\r
-        }\r
-\r
-        private void bSelectAll_Click(object sender, EventArgs e)\r
-        {\r
-            foreach(ListViewItem i in lvObject.Items)\r
-                i.Selected  = true;\r
-        }\r
-\r
-        private void bDeselectAll_Click(object sender, EventArgs e)\r
-        {\r
-            foreach(ListViewItem i in lvObject.Items)\r
-                i.Selected  = false;\r
-        }\r
-\r
-        private void bAssign_Click(object sender, EventArgs e)\r
-        {\r
-            try\r
-            {\r
-                TreeNode    n   = tvBone.SelectedNode;\r
-\r
-                if(n == null)\r
-                {\r
-                    MessageBox.Show("割り当てるボーンを選択してください");\r
-                    return;\r
-                }\r
-\r
-                foreach(ListViewItem i in lvObject.SelectedItems)\r
-                    i.SubItems[1].Text  = n.Text;\r
-\r
-                SaveAssign();\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-        }\r
-\r
-        private void bOk_Click(object sender, EventArgs e)\r
-        {\r
-            Color c = tabPage2.BackColor;\r
-\r
-            try\r
-            {\r
-                tabPage2.BackColor = Color.Tomato;\r
-                tabPage2.Update();\r
-                string file = tbMqoIn.Text;\r
-                OpenMQOFile(file);\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-            finally\r
-            {\r
-                tabPage2.BackColor = c;\r
-            }\r
-        }\r
-#endregion\r
-#region Merge UI\r
-        private void AddMergeTso(string[] files)\r
-        {\r
-            foreach(string i in files)\r
-            {\r
-                if(Path.GetExtension(files[0]).ToUpper() != ".TSO")\r
-                    continue;\r
-\r
-                if(tvMerge.Nodes.Find(i, false).Length == 0)\r
-                {\r
-                    TreeNode    node= tvMerge.Nodes.Add(i);\r
-                    node.Name       = i;\r
-                    node.Checked    = true;\r
-\r
-                    TSOFile     tso = new TSOFile(i);\r
-                    tso.ReadAll();\r
-\r
-                    foreach(TSOMesh j in tso.meshes)\r
-                    {\r
-                        TreeNode    mesh= node.Nodes.Add(j.Name);\r
-                        mesh.Name       = j.Name;\r
-                        mesh.Checked    = true;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        private void bMerge_Click(object sender, EventArgs e)\r
-        {\r
-            Color   c   = tabPage2.BackColor;\r
-\r
-            try\r
-            {\r
-                tabPage2.BackColor  = Color.Tomato;\r
-                List<TSOMesh>                               meshes      = new List<TSOMesh>();\r
-                Dictionary<string, Pair<TSOMaterial, int>>  materialmap = new Dictionary<string, Pair<TSOMaterial, int>>();\r
-                Dictionary<string, TSOTex>                  textures    = new Dictionary<string, TSOTex>();\r
-                TSOFile                                     last        = null;\r
-\r
-                foreach(TreeNode i in tvMerge.Nodes)\r
-                {\r
-                    TSOFile tso = new TSOFile(i.Text);\r
-                    last        = tso;\r
-                    ulong   mtls= 0;\r
-                    ulong   mask= 1;\r
-                    tso.ReadAll();\r
-\r
-                    foreach(TSOMesh j in tso.meshes)\r
-                    {\r
-                        TreeNode[]  found   = i.Nodes.Find(j.Name, false);\r
-\r
-                        if(found.Length == 0 || !found[0].Checked)\r
-                            continue;\r
-\r
-                        foreach(TSOSubMesh k in j.sub)\r
-                            mtls    |=1ul << k.spec;\r
-\r
-                        meshes.Add(j);\r
-                    }\r
-\r
-                    foreach(TSOMaterial j in tso.materials)\r
-                    {\r
-                        if((mask & mtls) != 0)\r
-                        {\r
-                            if(!materialmap.ContainsKey(j.Name))\r
-                            {\r
-                                Pair<TSOMaterial, int>  value   = new Pair<TSOMaterial,int>(j, materialmap.Count);\r
-                                materialmap.Add(j.Name, value);\r
-\r
-                                if(!textures.ContainsKey(j.ColorTex))\r
-                                {\r
-                                    TSOTex  tex = tso.texturemap[j.ColorTex];\r
-                                    textures.Add(tex.Name, tex);\r
-                                }\r
-\r
-                                if(!textures.ContainsKey(j.ShadeTex))\r
-                                {\r
-                                    TSOTex  tex = tso.texturemap[j.ShadeTex];\r
-                                    textures.Add(tex.Name, tex);\r
-                                }\r
-                            }\r
-                        }\r
-\r
-                        mask    <<=1;\r
-                    }\r
-                }\r
-\r
-                using(FileStream fs= File.OpenWrite(tbMergeTso.Text))\r
-                {\r
-                    fs.SetLength(0);\r
-\r
-                    List<TSOTex>    texlist = new List<TSOTex>(textures.Values);\r
-                    TSOMaterial[]   mtllist = new TSOMaterial[materialmap.Count];\r
-\r
-                    foreach(var i in materialmap.Values)\r
-                        mtllist[i.Second]   = i.First;\r
-\r
-                    foreach(TSOMesh i in meshes)\r
-                    {\r
-                        foreach(TSOSubMesh j in i.sub)\r
-                        {\r
-                            TSOMaterial mtl = i.file.materials[j.spec];\r
-                            j.spec          = materialmap[mtl.Name].Second;\r
-                        }\r
-                    }\r
-\r
-                    foreach(TSOTex i in texlist)\r
-                        TSOFile.ExchangeChannel(i.data, i.depth);\r
-\r
-                    BinaryWriter    bw  = new BinaryWriter(fs);\r
-                    TSOWriter.WriteHeader(bw);\r
-                    TSOWriter.Write(bw, last.nodes);\r
-                    TSOWriter.Write(bw, texlist.ToArray());\r
-                    TSOWriter.Write(bw, last.effects);\r
-                    TSOWriter.Write(bw, mtllist);\r
-                    TSOWriter.Write(bw, meshes.ToArray());\r
-                }\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            } finally\r
-            {\r
-                tabPage2.BackColor  = c;\r
-            }\r
-        }\r
-\r
-        private void bMergeAdd_Click(object sender, EventArgs e)\r
-        {\r
-            try\r
-            {\r
-                OpenFileDialog  dlg = new OpenFileDialog();\r
-                dlg.Filter      = "TSO File(*.tso)|*.tso";\r
-                dlg.Multiselect = true;\r
-\r
-                if(dlg.ShowDialog() == DialogResult.OK)\r
-                    AddMergeTso(dlg.FileNames);\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-        }\r
-\r
-        private void bMergeDel_Click(object sender, EventArgs e)\r
-        {\r
-            if(tvMerge.SelectedNode != null\r
-            && tvMerge.SelectedNode.Level == 0)\r
-                tvMerge.SelectedNode.Remove();\r
-        }\r
-\r
-        private void bMergeReset_Click(object sender, EventArgs e)\r
-        {\r
-            tvMerge.Nodes.Clear();\r
-        }\r
-\r
-        private void bRefMergeTso_Click(object sender, EventArgs e)\r
-        {\r
-            try\r
-            {\r
-                SaveFileDialog  dlg = new SaveFileDialog();\r
-                dlg.Filter  = "TSO File(*.tso)|*.tso";\r
-                dlg.FileName= tbMergeTso.Text;\r
-\r
-                if(dlg.ShowDialog() == DialogResult.OK)\r
-                    tbMergeTso.Text = dlg.FileName;\r
-            } catch(Exception ex)\r
-            {\r
-                Util.ProcessError(ex);\r
-            }\r
-        }\r
-\r
-        public static bool  bTvMerge_AfterCheck = false;\r
-\r
-        private void tvMerge_AfterCheck(object sender, TreeViewEventArgs e)\r
-        {\r
-            if(bTvMerge_AfterCheck)\r
-                return;\r
-\r
-            bTvMerge_AfterCheck = true;\r
-\r
-            try\r
-            {\r
-                if(e.Node.Level == 0)\r
-                {\r
-                    foreach(TreeNode i in e.Node.Nodes)\r
-                        i.Checked   = e.Node.Checked;\r
-                } else\r
-                {\r
-                    bool    check   = false;\r
-                  //bool    uncheck = false;\r
-\r
-                    foreach(TreeNode i in e.Node.Parent.Nodes)\r
-                    if(i.Checked)   check   = true;\r
-                  //else            uncheck = true;\r
-\r
-                    e.Node.Parent.Checked   = check;\r
-                }\r
-            } finally\r
-            {\r
-                bTvMerge_AfterCheck = false;\r
-            }\r
-        }\r
-#endregion\r
-    }\r
-\r
-    public class Util\r
-    {\r
-        public static void ProcessError(Exception e)\r
-        {\r
-            MessageBox.Show(e.ToString());\r
-        }\r
-    }\r
-}\r
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.IO;
+using System.Text;
+using System.Windows.Forms;
+using Microsoft.Win32;
+
+namespace Tso2MqoGui
+{
+    public partial class Form1 : Form
+    {
+        public Form1()
+        {
+            InitializeComponent();
+        }
+
+        private void Form1_Load(object sender, EventArgs e)
+        {
+            RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");
+            tbPath.Text = (string)reg.GetValue("OutPath", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
+            tabControl1.SelectedIndex = (int)reg.GetValue("TabPage", 0);
+            tbMqoFile.Text = (string)reg.GetValue("MqoIn", "");
+            tbTsoFileRef.Text = (string)reg.GetValue("Tso", "");
+            tbTsoFile.Text = (string)reg.GetValue("TsoEx", "");
+            tbMergeTso.Text = (string)reg.GetValue("MergeTso", "");
+            rbRefBone.Checked = (int)reg.GetValue("RefBone", 1) == 1;
+            rbOneBone.Checked = (int)reg.GetValue("OneBone", 0) == 1;
+            rbBoneNone.Checked = (int)reg.GetValue("BoneNone", 1) == 1;
+            rbBoneRokDeBone.Checked = (int)reg.GetValue("BoneRokDeBone", 0) == 1;
+            cbMakeSub.Checked = (int)reg.GetValue("MakeSub", 1) == 1;
+            cbCopyTSO.Checked = (int)reg.GetValue("CopyTSO", 1) == 1;
+            cbShowMaterials.Checked = (int)reg.GetValue("ShowMaterials", 0) == 1;
+
+            reg = Application.UserAppDataRegistry.CreateSubKey("Form1");
+            Bounds = new Rectangle(
+                (int)reg.GetValue("Left", 0),
+                (int)reg.GetValue("Top", 0),
+                (int)reg.GetValue("Width", 640),
+                (int)reg.GetValue("Height", 320));
+
+            EnableControlStuff();
+
+            Config config = Config.Instance;
+        }
+
+        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
+        {
+            RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");
+            reg.SetValue("OutPath", tbPath.Text);
+            reg.SetValue("TabPage", tabControl1.SelectedIndex);
+            reg.SetValue("MqoIn", tbMqoFile.Text);
+            reg.SetValue("Tso", tbTsoFileRef.Text);
+            reg.SetValue("TsoEx", tbTsoFile.Text);
+            reg.SetValue("MergeTso", tbMergeTso.Text);
+            reg.SetValue("RefBone", rbRefBone.Checked ? 1 : 0);
+            reg.SetValue("OneBone", rbOneBone.Checked ? 1 : 0);
+            reg.SetValue("BoneNone", rbBoneNone.Checked ? 1 : 0);
+            reg.SetValue("BoneRokDeBone", rbBoneRokDeBone.Checked ? 1 : 0);
+            reg.SetValue("MakeSub", cbMakeSub.Checked ? 1 : 0);
+            reg.SetValue("CopyTSO", cbCopyTSO.Checked ? 1 : 0);
+            reg.SetValue("ShowMaterials", cbShowMaterials.Checked ? 1 : 0);
+
+            reg = Application.UserAppDataRegistry.CreateSubKey("Form1");
+
+            if ((this.WindowState & FormWindowState.Minimized) == FormWindowState.Minimized)
+            {
+                reg.SetValue("Top", RestoreBounds.Top);
+                reg.SetValue("Left", RestoreBounds.Left);
+                reg.SetValue("Width", RestoreBounds.Width);
+                reg.SetValue("Height", RestoreBounds.Height);
+            }
+            else
+            {
+                reg.SetValue("Top", Top);
+                reg.SetValue("Left", Left);
+                reg.SetValue("Width", Width);
+                reg.SetValue("Height", Height);
+            }
+
+            Config.Save();
+        }
+
+        private void Form1_DragDrop(object sender, DragEventArgs e)
+        {
+            try
+            {
+                if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+                    return;
+
+                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
+
+                if (files.Length == 0)
+                    return;
+
+                switch (tabControl1.SelectedIndex)
+                {
+                    case 0:
+                        foreach (string i in files)
+                        {
+                            if (Path.GetExtension(i).ToUpper() == ".TSO")
+                                GenerateMqo(i);
+                        }
+
+                        break;
+
+                    case 1:
+                        switch (Path.GetExtension(files[0]).ToUpper())
+                        {
+                            case ".TSO": tbTsoFileRef.Text = files[0]; break;
+                            case ".MQO": tbMqoFile.Text = files[0]; break;
+                        }
+
+                        break;
+
+                    case 2:
+                        AddMergeTso(files);
+                        break;
+                }
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+        }
+
+        private void Form1_DragEnter(object sender, DragEventArgs e)
+        {
+            if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+                return;
+
+            e.Effect = DragDropEffects.Copy;
+        }
+
+        private void tbMergeTso_DragDrop(object sender, DragEventArgs e)
+        {
+            if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+                return;
+
+            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
+
+            switch (Path.GetExtension(files[0]).ToUpper())
+            {
+                case ".TSO": tbMergeTso.Text = files[0]; break;
+            }
+        }
+
+        private void tbMergeTso_DragEnter(object sender, DragEventArgs e)
+        {
+            if (!e.Data.GetDataPresent(DataFormats.FileDrop))
+                return;
+
+            e.Effect = DragDropEffects.Copy;
+        }
+
+        private void GenerateMqo(string tso_file)
+        {
+            string out_path = tbPath.Text;
+
+            if (cbMakeSub.Checked)
+            {
+                out_path = Path.Combine(out_path, Path.GetFileNameWithoutExtension(tso_file));
+                Directory.CreateDirectory(out_path);
+            }
+
+            try
+            {
+                label2.BackColor = Color.Tomato;
+                label2.ForeColor = Color.White;
+                label2.Text = "Processing";
+                label2.Invalidate();
+                label2.Update();
+
+                MqoGenerator gen = new MqoGenerator();
+                gen.Generate(tso_file, out_path, rbBoneRokDeBone.Checked);
+
+                if (cbCopyTSO.Checked)
+                {
+                    string tso_path = Path.Combine(out_path, Path.GetFileName(tso_file));
+
+                    if (tso_file != tso_path)
+                        File.Copy(tso_file, tso_path, true);
+                }
+            }
+            finally
+            {
+                label2.BackColor = SystemColors.Control;
+                label2.BackColor = label2.Parent.BackColor;
+                label2.ForeColor = SystemColors.ControlText;
+                label2.Text = "Drop TSO File Here!";
+            }
+        }
+
+        private void GenerateTso(string file)
+        {
+            TSOGeneratorConfig config = new TSOGeneratorConfig();
+            config.ShowMaterials = cbShowMaterials.Checked;
+
+            if (rbRefBone.Checked)
+            {
+                TSOGeneratorMqxBone gen = new TSOGeneratorMqxBone(config);
+                gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);
+            }
+            else if (rbOneBone.Checked)
+            {
+                TSOGeneratorOneBone gen = new TSOGeneratorOneBone(config);
+
+                foreach (ListViewItem item in lvObjects.Items)
+                {
+                    if (item.SubItems[1].Text == "")
+                    {
+                        MessageBox.Show("すべてのオブジェクトにボーンを設定してください");
+                        return;
+                    }
+
+                    gen.ObjectBoneNames.Add(item.SubItems[0].Text, item.SubItems[1].Text);
+                }
+
+                gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);
+            }
+        }
+        #region tso->mqo UI
+        private void button1_Click(object sender, EventArgs e)
+        {
+            FolderBrowserDialog dlg = new FolderBrowserDialog();
+            dlg.SelectedPath = tbPath.Text;
+
+            if (dlg.ShowDialog() == DialogResult.OK)
+                tbPath.Text = dlg.SelectedPath;
+        }
+        #endregion
+        #region mqo->tso UI
+        private void radioButton1_CheckedChanged(object sender, EventArgs e)
+        {
+            EnableControlStuff();
+        }
+
+        private void radioButton2_CheckedChanged(object sender, EventArgs e)
+        {
+            EnableControlStuff();
+        }
+
+        private void EnableControlStuff()
+        {
+            gbBone.Enabled = rbOneBone.Checked;
+        }
+
+        private void BuildBoneTree(TreeNodeCollection nodes, TSONode node)
+        {
+            TreeNode tn = nodes.Add(node.Name);
+            tn.Tag = node;
+
+            if (node.children != null)
+                foreach (TSONode i in node.children)
+                    BuildBoneTree(tn.Nodes, i);
+        }
+
+        private void SaveAssign()
+        {
+            foreach (ListViewItem item in lvObjects.Items)
+            {
+                string obj = item.SubItems[0].Text;
+                string bone = item.SubItems[1].Text;
+
+                if (Config.Instance.object_bone_map.ContainsKey(obj))
+                    Config.Instance.object_bone_map[obj] = bone;
+                else
+                    Config.Instance.object_bone_map.Add(obj, bone);
+            }
+        }
+
+        private void btnMqoFile_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                OpenFileDialog dlg = new OpenFileDialog();
+                dlg.Filter = "Metasequoia File (*.mqo)|*.mqo";
+                dlg.FileName = tbMqoFile.Text;
+
+                if (dlg.ShowDialog() == DialogResult.OK)
+                    tbMqoFile.Text = dlg.FileName;
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+        }
+
+        private void btnTsoFileRef_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                OpenFileDialog dlg = new OpenFileDialog();
+                dlg.Filter = "TSO File (*.tso)|*.tso";
+                dlg.FileName = tbTsoFileRef.Text;
+
+                if (dlg.ShowDialog() == DialogResult.OK)
+                    tbTsoFileRef.Text = dlg.FileName;
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+        }
+
+        private void btnTsoFile_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                SaveFileDialog dlg = new SaveFileDialog();
+                dlg.Filter = "TSO File (*.tso)|*.tso";
+                dlg.FileName = tbTsoFile.Text;
+
+                if (dlg.ShowDialog() == DialogResult.OK)
+                    tbTsoFile.Text = dlg.FileName;
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+        }
+
+        private void btnRefresh_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                // 一旦現状を保存
+                SaveAssign();
+
+                // オブジェクト
+                MqoReader mqo = new MqoReader();
+                mqo.Load(tbMqoFile.Text);
+                lvObjects.Items.Clear();
+
+                foreach (MqoObject obj in mqo.Objects)
+                {
+                    ListViewItem item = lvObjects.Items.Add(obj.name);
+                    item.Tag = obj;
+                    string bone;
+
+                    if (Config.Instance.object_bone_map.TryGetValue(obj.name, out bone))
+                        item.SubItems.Add(bone);
+                    else
+                        item.SubItems.Add("");
+                }
+
+                // ボーン構造
+                TSOFile tso = new TSOFile(tbTsoFileRef.Text);
+                tso.ReadAll();
+                tvBones.Visible = false;
+                tvBones.Nodes.Clear();
+                BuildBoneTree(tvBones.Nodes, tso.nodes[0]);
+                tvBones.ExpandAll();
+                tvBones.Nodes[0].EnsureVisible();
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+            finally
+            {
+                tvBones.Visible = true;
+            }
+        }
+
+        private void btnSelectAll_Click(object sender, EventArgs e)
+        {
+            foreach (ListViewItem item in lvObjects.Items)
+                item.Selected = true;
+        }
+
+        private void btnDeselectAll_Click(object sender, EventArgs e)
+        {
+            foreach (ListViewItem item in lvObjects.Items)
+                item.Selected = false;
+        }
+
+        private void btnAssign_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                TreeNode node = tvBones.SelectedNode;
+
+                if (node == null)
+                {
+                    MessageBox.Show("割り当てるボーンを選択してください");
+                    return;
+                }
+
+                foreach (ListViewItem item in lvObjects.SelectedItems)
+                    item.SubItems[1].Text = node.Text;
+
+                SaveAssign();
+            }
+            catch (Exception ex)
+            {
+                Util.ProcessError(ex);
+            }
+        }
+
+        private void btnGenerate_Click(object sender, EventArgs e)
+        {
+            Color c = tabPage2.BackColor;
+
+            try
+            {
+                tabPage2.BackColor = Color.Tomato;
+                tabPage2.Update();
+                string file = tbMqoFile.Text;
+                GenerateTso(file);
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+            finally
+            {
+                tabPage2.BackColor = c;
+            }
+        }
+        #endregion
+        #region Merge UI
+        private void AddMergeTso(string[] files)
+        {
+            foreach (string file in files)
+            {
+                if (Path.GetExtension(files[0]).ToUpper() != ".TSO")
+                    continue;
+
+                if (tvMerge.Nodes.Find(file, false).Length == 0)
+                {
+                    TreeNode node = tvMerge.Nodes.Add(file);
+                    node.Name = file;
+                    node.Checked = true;
+
+                    TSOFile tso = new TSOFile(file);
+                    tso.ReadAll();
+
+                    foreach (TSOMesh j in tso.meshes)
+                    {
+                        TreeNode mesh = node.Nodes.Add(j.Name);
+                        mesh.Name = j.Name;
+                        mesh.Checked = true;
+                    }
+                }
+            }
+        }
+
+        private void btnMerge_Click(object sender, EventArgs e)
+        {
+            Color c = tabPage2.BackColor;
+
+            try
+            {
+                tabPage2.BackColor = Color.Tomato;
+                List<TSOMesh> meshes = new List<TSOMesh>();
+                Dictionary<string, Pair<TSOMaterial, int>> materialmap = new Dictionary<string, Pair<TSOMaterial, int>>();
+                Dictionary<string, TSOTex> textures = new Dictionary<string, TSOTex>();
+                TSOFile last = null;
+
+                foreach (TreeNode node in tvMerge.Nodes)
+                {
+                    TSOFile tso = new TSOFile(node.Text);
+                    last = tso;
+                    ulong mtls = 0;
+                    ulong mask = 1;
+                    tso.ReadAll();
+
+                    foreach (TSOMesh mesh in tso.meshes)
+                    {
+                        TreeNode[] found = node.Nodes.Find(mesh.Name, false);
+
+                        if (found.Length == 0 || !found[0].Checked)
+                            continue;
+
+                        foreach (TSOSubMesh k in mesh.sub_meshes)
+                            mtls |= 1ul << k.spec;
+
+                        meshes.Add(mesh);
+                    }
+
+                    foreach (TSOMaterial mat in tso.materials)
+                    {
+                        if ((mask & mtls) != 0)
+                        {
+                            if (!materialmap.ContainsKey(mat.Name))
+                            {
+                                Pair<TSOMaterial, int> value = new Pair<TSOMaterial, int>(mat, materialmap.Count);
+                                materialmap.Add(mat.Name, value);
+
+                                if (!textures.ContainsKey(mat.ColorTex))
+                                {
+                                    TSOTex tex = tso.texturemap[mat.ColorTex];
+                                    textures.Add(tex.Name, tex);
+                                }
+
+                                if (!textures.ContainsKey(mat.ShadeTex))
+                                {
+                                    TSOTex tex = tso.texturemap[mat.ShadeTex];
+                                    textures.Add(tex.Name, tex);
+                                }
+                            }
+                        }
+
+                        mask <<= 1;
+                    }
+                }
+
+                using (FileStream fs = File.OpenWrite(tbMergeTso.Text))
+                {
+                    fs.SetLength(0);
+
+                    List<TSOTex> texlist = new List<TSOTex>(textures.Values);
+                    TSOMaterial[] mtllist = new TSOMaterial[materialmap.Count];
+
+                    foreach (var i in materialmap.Values)
+                        mtllist[i.Second] = i.First;
+
+                    foreach (TSOMesh mesh in meshes)
+                    {
+                        foreach (TSOSubMesh sub in mesh.sub_meshes)
+                        {
+                            TSOMaterial spec = mesh.file.materials[sub.spec];
+                            sub.spec = materialmap[spec.Name].Second;
+                        }
+                    }
+
+                    foreach (TSOTex tex in texlist)
+                        TSOFile.ExchangeChannel(tex.data, tex.depth);
+
+                    BinaryWriter bw = new BinaryWriter(fs);
+                    TSOWriter.WriteHeader(bw);
+                    TSOWriter.Write(bw, last.nodes);
+                    TSOWriter.Write(bw, texlist.ToArray());
+                    TSOWriter.Write(bw, last.effects);
+                    TSOWriter.Write(bw, mtllist);
+                    TSOWriter.Write(bw, meshes.ToArray());
+                }
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+            finally
+            {
+                tabPage2.BackColor = c;
+            }
+        }
+
+        private void btnMergeAdd_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                OpenFileDialog dlg = new OpenFileDialog();
+                dlg.Filter = "TSO File(*.tso)|*.tso";
+                dlg.Multiselect = true;
+
+                if (dlg.ShowDialog() == DialogResult.OK)
+                    AddMergeTso(dlg.FileNames);
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+        }
+
+        private void btnMergeDel_Click(object sender, EventArgs e)
+        {
+            if (tvMerge.SelectedNode != null && tvMerge.SelectedNode.Level == 0)
+                tvMerge.SelectedNode.Remove();
+        }
+
+        private void btnMergeReset_Click(object sender, EventArgs e)
+        {
+            tvMerge.Nodes.Clear();
+        }
+
+        private void btnRefMergeTso_Click(object sender, EventArgs e)
+        {
+            try
+            {
+                SaveFileDialog dlg = new SaveFileDialog();
+                dlg.Filter = "TSO File (*.tso)|*.tso";
+                dlg.FileName = tbMergeTso.Text;
+
+                if (dlg.ShowDialog() == DialogResult.OK)
+                    tbMergeTso.Text = dlg.FileName;
+            }
+            catch (Exception exception)
+            {
+                Util.ProcessError(exception);
+            }
+        }
+
+        public static bool bTvMerge_AfterCheck = false;
+
+        private void tvMerge_AfterCheck(object sender, TreeViewEventArgs e)
+        {
+            if (bTvMerge_AfterCheck)
+                return;
+
+            bTvMerge_AfterCheck = true;
+
+            try
+            {
+                if (e.Node.Level == 0)
+                {
+                    foreach (TreeNode node in e.Node.Nodes)
+                        node.Checked = e.Node.Checked;
+                }
+                else
+                {
+                    bool check = false;
+
+                    foreach (TreeNode node in e.Node.Parent.Nodes)
+                        if (node.Checked) check = true;
+
+                    e.Node.Parent.Checked = check;
+                }
+            }
+            finally
+            {
+                bTvMerge_AfterCheck = false;
+            }
+        }
+        #endregion
+    }
+
+    public class Util
+    {
+        public static void ProcessError(Exception exception)
+        {
+            MessageBox.Show(exception.ToString());
+        }
+    }
+}