OSDN Git Service

remove MqoBoneMode. use bool MqxEnabled.
[tdcgexplorer/tso2mqo.git] / Form1.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.IO;
7 using System.Text;
8 using System.Windows.Forms;
9 using Microsoft.Win32;
10
11 namespace Tso2MqoGui
12 {
13     public partial class Form1 : Form
14     {
15         public Form1()
16         {
17             InitializeComponent();
18         }
19
20         private void Form1_Load(object sender, EventArgs e)
21         {
22             RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");
23             tbPath.Text = (string)reg.GetValue("OutPath", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
24             tabControl1.SelectedIndex = (int)reg.GetValue("TabPage", 0);
25             tbMqoFile.Text = (string)reg.GetValue("MqoIn", "");
26             tbTsoFileRef.Text = (string)reg.GetValue("Tso", "");
27             tbTsoFile.Text = (string)reg.GetValue("TsoEx", "");
28             tbMergeTso.Text = (string)reg.GetValue("MergeTso", "");
29             rbRefBone.Checked = (int)reg.GetValue("RefBone", 1) == 1;
30             rbOneBone.Checked = (int)reg.GetValue("OneBone", 0) == 1;
31             rbBoneNone.Checked = (int)reg.GetValue("BoneNone", 1) == 1;
32             rbBoneRokDeBone.Checked = (int)reg.GetValue("BoneRokDeBone", 0) == 1;
33             cbMakeSub.Checked = (int)reg.GetValue("MakeSub", 1) == 1;
34             cbCopyTSO.Checked = (int)reg.GetValue("CopyTSO", 1) == 1;
35             cbShowMaterials.Checked = (int)reg.GetValue("ShowMaterials", 0) == 1;
36
37             reg = Application.UserAppDataRegistry.CreateSubKey("Form1");
38             Bounds = new Rectangle(
39                 (int)reg.GetValue("Left", 0),
40                 (int)reg.GetValue("Top", 0),
41                 (int)reg.GetValue("Width", 640),
42                 (int)reg.GetValue("Height", 320));
43
44             EnableControlStuff();
45
46             Config config = Config.Instance;
47         }
48
49         private void Form1_FormClosed(object sender, FormClosedEventArgs e)
50         {
51             RegistryKey reg = Application.UserAppDataRegistry.CreateSubKey("Config");
52             reg.SetValue("OutPath", tbPath.Text);
53             reg.SetValue("TabPage", tabControl1.SelectedIndex);
54             reg.SetValue("MqoIn", tbMqoFile.Text);
55             reg.SetValue("Tso", tbTsoFileRef.Text);
56             reg.SetValue("TsoEx", tbTsoFile.Text);
57             reg.SetValue("MergeTso", tbMergeTso.Text);
58             reg.SetValue("RefBone", rbRefBone.Checked ? 1 : 0);
59             reg.SetValue("OneBone", rbOneBone.Checked ? 1 : 0);
60             reg.SetValue("BoneNone", rbBoneNone.Checked ? 1 : 0);
61             reg.SetValue("BoneRokDeBone", rbBoneRokDeBone.Checked ? 1 : 0);
62             reg.SetValue("MakeSub", cbMakeSub.Checked ? 1 : 0);
63             reg.SetValue("CopyTSO", cbCopyTSO.Checked ? 1 : 0);
64             reg.SetValue("ShowMaterials", cbShowMaterials.Checked ? 1 : 0);
65
66             reg = Application.UserAppDataRegistry.CreateSubKey("Form1");
67
68             if ((this.WindowState & FormWindowState.Minimized) == FormWindowState.Minimized)
69             {
70                 reg.SetValue("Top", RestoreBounds.Top);
71                 reg.SetValue("Left", RestoreBounds.Left);
72                 reg.SetValue("Width", RestoreBounds.Width);
73                 reg.SetValue("Height", RestoreBounds.Height);
74             }
75             else
76             {
77                 reg.SetValue("Top", Top);
78                 reg.SetValue("Left", Left);
79                 reg.SetValue("Width", Width);
80                 reg.SetValue("Height", Height);
81             }
82
83             Config.Save();
84         }
85
86         private void Form1_DragDrop(object sender, DragEventArgs e)
87         {
88             try
89             {
90                 if (!e.Data.GetDataPresent(DataFormats.FileDrop))
91                     return;
92
93                 string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
94
95                 if (files.Length == 0)
96                     return;
97
98                 switch (tabControl1.SelectedIndex)
99                 {
100                     case 0:
101                         foreach (string i in files)
102                         {
103                             if (Path.GetExtension(i).ToUpper() == ".TSO")
104                                 GenerateMqo(i);
105                         }
106
107                         break;
108
109                     case 1:
110                         switch (Path.GetExtension(files[0]).ToUpper())
111                         {
112                             case ".TSO": tbTsoFileRef.Text = files[0]; break;
113                             case ".MQO": tbMqoFile.Text = files[0]; break;
114                         }
115
116                         break;
117
118                     case 2:
119                         AddMergeTso(files);
120                         break;
121                 }
122             }
123             catch (Exception exception)
124             {
125                 Util.ProcessError(exception);
126             }
127         }
128
129         private void Form1_DragEnter(object sender, DragEventArgs e)
130         {
131             if (!e.Data.GetDataPresent(DataFormats.FileDrop))
132                 return;
133
134             e.Effect = DragDropEffects.Copy;
135         }
136
137         private void tbMergeTso_DragDrop(object sender, DragEventArgs e)
138         {
139             if (!e.Data.GetDataPresent(DataFormats.FileDrop))
140                 return;
141
142             string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
143
144             switch (Path.GetExtension(files[0]).ToUpper())
145             {
146                 case ".TSO": tbMergeTso.Text = files[0]; break;
147             }
148         }
149
150         private void tbMergeTso_DragEnter(object sender, DragEventArgs e)
151         {
152             if (!e.Data.GetDataPresent(DataFormats.FileDrop))
153                 return;
154
155             e.Effect = DragDropEffects.Copy;
156         }
157
158         private void GenerateMqo(string tso_file)
159         {
160             string out_path = tbPath.Text;
161
162             if (cbMakeSub.Checked)
163             {
164                 out_path = Path.Combine(out_path, Path.GetFileNameWithoutExtension(tso_file));
165                 Directory.CreateDirectory(out_path);
166             }
167
168             try
169             {
170                 label2.BackColor = Color.Tomato;
171                 label2.ForeColor = Color.White;
172                 label2.Text = "Processing";
173                 label2.Invalidate();
174                 label2.Update();
175
176                 MqoGenerator gen = new MqoGenerator();
177                 gen.Generate(tso_file, out_path, rbBoneRokDeBone.Checked);
178
179                 if (cbCopyTSO.Checked)
180                 {
181                     string tso_path = Path.Combine(out_path, Path.GetFileName(tso_file));
182
183                     if (tso_file != tso_path)
184                         File.Copy(tso_file, tso_path, true);
185                 }
186             }
187             finally
188             {
189                 label2.BackColor = SystemColors.Control;
190                 label2.BackColor = label2.Parent.BackColor;
191                 label2.ForeColor = SystemColors.ControlText;
192                 label2.Text = "Drop TSO File Here!";
193             }
194         }
195
196         private void GenerateTso(string file)
197         {
198             TSOGeneratorConfig config = new TSOGeneratorConfig();
199             config.ShowMaterials = cbShowMaterials.Checked;
200
201             if (rbRefBone.Checked)
202             {
203                 TSOGeneratorRefBone gen = new TSOGeneratorRefBone(config);
204                 gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);
205             }
206             else
207                 if (rbOneBone.Checked)
208                 {
209                     TSOGeneratorOneBone gen = new TSOGeneratorOneBone(config);
210
211                     foreach (ListViewItem item in lvObjects.Items)
212                     {
213                         if (item.SubItems[1].Text == "")
214                         {
215                             MessageBox.Show("すべてのオブジェクトにボーンを設定してください");
216                             return;
217                         }
218
219                         gen.ObjectBoneNames.Add(item.SubItems[0].Text, item.SubItems[1].Text);
220                     }
221
222                     gen.Generate(file, tbTsoFileRef.Text, tbTsoFile.Text);
223                 }
224                 else
225                 {
226                 }
227         }
228         #region tso->mqo UI
229         private void button1_Click(object sender, EventArgs e)
230         {
231             FolderBrowserDialog dlg = new FolderBrowserDialog();
232             dlg.SelectedPath = tbPath.Text;
233
234             if (dlg.ShowDialog() == DialogResult.OK)
235                 tbPath.Text = dlg.SelectedPath;
236         }
237         #endregion
238         #region mqo->tso UI
239         private void radioButton1_CheckedChanged(object sender, EventArgs e)
240         {
241             EnableControlStuff();
242         }
243
244         private void radioButton2_CheckedChanged(object sender, EventArgs e)
245         {
246             EnableControlStuff();
247         }
248
249         private void EnableControlStuff()
250         {
251             gbBone.Enabled = rbOneBone.Checked;
252         }
253
254         private void BuildBoneTree(TreeNodeCollection nodes, TSONode node)
255         {
256             TreeNode tn = nodes.Add(node.ShortName);
257             tn.Tag = node;
258
259             if (node.children != null)
260                 foreach (TSONode i in node.children)
261                     BuildBoneTree(tn.Nodes, i);
262         }
263
264         private void SaveAssign()
265         {
266             foreach (ListViewItem item in lvObjects.Items)
267             {
268                 string obj = item.SubItems[0].Text;
269                 string bone = item.SubItems[1].Text;
270
271                 if (Config.Instance.object_bone_map.ContainsKey(obj))
272                     Config.Instance.object_bone_map[obj] = bone;
273                 else
274                     Config.Instance.object_bone_map.Add(obj, bone);
275             }
276         }
277
278         private void btnMqoFile_Click(object sender, EventArgs e)
279         {
280             try
281             {
282                 OpenFileDialog dlg = new OpenFileDialog();
283                 dlg.Filter = "Metasequoia File (*.mqo)|*.mqo";
284                 dlg.FileName = tbMqoFile.Text;
285
286                 if (dlg.ShowDialog() == DialogResult.OK)
287                     tbMqoFile.Text = dlg.FileName;
288             }
289             catch (Exception exception)
290             {
291                 Util.ProcessError(exception);
292             }
293         }
294
295         private void btnTsoFileRef_Click(object sender, EventArgs e)
296         {
297             try
298             {
299                 OpenFileDialog dlg = new OpenFileDialog();
300                 dlg.Filter = "TSO File (*.tso)|*.tso";
301                 dlg.FileName = tbTsoFileRef.Text;
302
303                 if (dlg.ShowDialog() == DialogResult.OK)
304                     tbTsoFileRef.Text = dlg.FileName;
305             }
306             catch (Exception exception)
307             {
308                 Util.ProcessError(exception);
309             }
310         }
311
312         private void btnTsoFile_Click(object sender, EventArgs e)
313         {
314             try
315             {
316                 SaveFileDialog dlg = new SaveFileDialog();
317                 dlg.Filter = "TSO File (*.tso)|*.tso";
318                 dlg.FileName = tbTsoFile.Text;
319
320                 if (dlg.ShowDialog() == DialogResult.OK)
321                     tbTsoFile.Text = dlg.FileName;
322             }
323             catch (Exception exception)
324             {
325                 Util.ProcessError(exception);
326             }
327         }
328
329         private void btnRefresh_Click(object sender, EventArgs e)
330         {
331             try
332             {
333                 // 一旦現状を保存
334                 SaveAssign();
335
336                 // オブジェクト
337                 MqoFile mqo = new MqoFile();
338                 mqo.Load(tbMqoFile.Text);
339                 lvObjects.Items.Clear();
340
341                 foreach (MqoObject obj in mqo.Objects)
342                 {
343                     ListViewItem item = lvObjects.Items.Add(obj.name);
344                     item.Tag = obj;
345                     string bone;
346
347                     if (Config.Instance.object_bone_map.TryGetValue(obj.name, out bone))
348                         item.SubItems.Add(bone);
349                     else
350                         item.SubItems.Add("");
351                 }
352
353                 // ボーン構造
354                 TSOFile tso = new TSOFile(tbTsoFileRef.Text);
355                 tso.ReadAll();
356                 tvBones.Visible = false;
357                 tvBones.Nodes.Clear();
358                 BuildBoneTree(tvBones.Nodes, tso.nodes[0]);
359                 tvBones.ExpandAll();
360                 tvBones.Nodes[0].EnsureVisible();
361             }
362             catch (Exception exception)
363             {
364                 Util.ProcessError(exception);
365             }
366             finally
367             {
368                 tvBones.Visible = true;
369             }
370         }
371
372         private void btnSelectAll_Click(object sender, EventArgs e)
373         {
374             foreach (ListViewItem item in lvObjects.Items)
375                 item.Selected = true;
376         }
377
378         private void btnDeselectAll_Click(object sender, EventArgs e)
379         {
380             foreach (ListViewItem item in lvObjects.Items)
381                 item.Selected = false;
382         }
383
384         private void btnAssign_Click(object sender, EventArgs e)
385         {
386             try
387             {
388                 TreeNode node = tvBones.SelectedNode;
389
390                 if (node == null)
391                 {
392                     MessageBox.Show("割り当てるボーンを選択してください");
393                     return;
394                 }
395
396                 foreach (ListViewItem item in lvObjects.SelectedItems)
397                     item.SubItems[1].Text = node.Text;
398
399                 SaveAssign();
400             }
401             catch (Exception ex)
402             {
403                 Util.ProcessError(ex);
404             }
405         }
406
407         private void btnGenerate_Click(object sender, EventArgs e)
408         {
409             Color c = tabPage2.BackColor;
410
411             try
412             {
413                 tabPage2.BackColor = Color.Tomato;
414                 tabPage2.Update();
415                 string file = tbMqoFile.Text;
416                 GenerateTso(file);
417             }
418             catch (Exception exception)
419             {
420                 Util.ProcessError(exception);
421             }
422             finally
423             {
424                 tabPage2.BackColor = c;
425             }
426         }
427         #endregion
428         #region Merge UI
429         private void AddMergeTso(string[] files)
430         {
431             foreach (string file in files)
432             {
433                 if (Path.GetExtension(files[0]).ToUpper() != ".TSO")
434                     continue;
435
436                 if (tvMerge.Nodes.Find(file, false).Length == 0)
437                 {
438                     TreeNode node = tvMerge.Nodes.Add(file);
439                     node.Name = file;
440                     node.Checked = true;
441
442                     TSOFile tso = new TSOFile(file);
443                     tso.ReadAll();
444
445                     foreach (TSOMesh j in tso.meshes)
446                     {
447                         TreeNode mesh = node.Nodes.Add(j.Name);
448                         mesh.Name = j.Name;
449                         mesh.Checked = true;
450                     }
451                 }
452             }
453         }
454
455         private void btnMerge_Click(object sender, EventArgs e)
456         {
457             Color c = tabPage2.BackColor;
458
459             try
460             {
461                 tabPage2.BackColor = Color.Tomato;
462                 List<TSOMesh> meshes = new List<TSOMesh>();
463                 Dictionary<string, Pair<TSOMaterial, int>> materialmap = new Dictionary<string, Pair<TSOMaterial, int>>();
464                 Dictionary<string, TSOTex> textures = new Dictionary<string, TSOTex>();
465                 TSOFile last = null;
466
467                 foreach (TreeNode node in tvMerge.Nodes)
468                 {
469                     TSOFile tso = new TSOFile(node.Text);
470                     last = tso;
471                     ulong mtls = 0;
472                     ulong mask = 1;
473                     tso.ReadAll();
474
475                     foreach (TSOMesh mesh in tso.meshes)
476                     {
477                         TreeNode[] found = node.Nodes.Find(mesh.Name, false);
478
479                         if (found.Length == 0 || !found[0].Checked)
480                             continue;
481
482                         foreach (TSOSubMesh k in mesh.sub_meshes)
483                             mtls |= 1ul << k.spec;
484
485                         meshes.Add(mesh);
486                     }
487
488                     foreach (TSOMaterial mat in tso.materials)
489                     {
490                         if ((mask & mtls) != 0)
491                         {
492                             if (!materialmap.ContainsKey(mat.Name))
493                             {
494                                 Pair<TSOMaterial, int> value = new Pair<TSOMaterial, int>(mat, materialmap.Count);
495                                 materialmap.Add(mat.Name, value);
496
497                                 if (!textures.ContainsKey(mat.ColorTex))
498                                 {
499                                     TSOTex tex = tso.texturemap[mat.ColorTex];
500                                     textures.Add(tex.Name, tex);
501                                 }
502
503                                 if (!textures.ContainsKey(mat.ShadeTex))
504                                 {
505                                     TSOTex tex = tso.texturemap[mat.ShadeTex];
506                                     textures.Add(tex.Name, tex);
507                                 }
508                             }
509                         }
510
511                         mask <<= 1;
512                     }
513                 }
514
515                 using (FileStream fs = File.OpenWrite(tbMergeTso.Text))
516                 {
517                     fs.SetLength(0);
518
519                     List<TSOTex> texlist = new List<TSOTex>(textures.Values);
520                     TSOMaterial[] mtllist = new TSOMaterial[materialmap.Count];
521
522                     foreach (var i in materialmap.Values)
523                         mtllist[i.Second] = i.First;
524
525                     foreach (TSOMesh mesh in meshes)
526                     {
527                         foreach (TSOSubMesh sub in mesh.sub_meshes)
528                         {
529                             TSOMaterial mtl = mesh.file.materials[sub.spec];
530                             sub.spec = materialmap[mtl.Name].Second;
531                         }
532                     }
533
534                     foreach (TSOTex tex in texlist)
535                         TSOFile.ExchangeChannel(tex.data, tex.depth);
536
537                     BinaryWriter bw = new BinaryWriter(fs);
538                     TSOWriter.WriteHeader(bw);
539                     TSOWriter.Write(bw, last.nodes);
540                     TSOWriter.Write(bw, texlist.ToArray());
541                     TSOWriter.Write(bw, last.effects);
542                     TSOWriter.Write(bw, mtllist);
543                     TSOWriter.Write(bw, meshes.ToArray());
544                 }
545             }
546             catch (Exception exception)
547             {
548                 Util.ProcessError(exception);
549             }
550             finally
551             {
552                 tabPage2.BackColor = c;
553             }
554         }
555
556         private void btnMergeAdd_Click(object sender, EventArgs e)
557         {
558             try
559             {
560                 OpenFileDialog dlg = new OpenFileDialog();
561                 dlg.Filter = "TSO File(*.tso)|*.tso";
562                 dlg.Multiselect = true;
563
564                 if (dlg.ShowDialog() == DialogResult.OK)
565                     AddMergeTso(dlg.FileNames);
566             }
567             catch (Exception exception)
568             {
569                 Util.ProcessError(exception);
570             }
571         }
572
573         private void btnMergeDel_Click(object sender, EventArgs e)
574         {
575             if (tvMerge.SelectedNode != null && tvMerge.SelectedNode.Level == 0)
576                 tvMerge.SelectedNode.Remove();
577         }
578
579         private void btnMergeReset_Click(object sender, EventArgs e)
580         {
581             tvMerge.Nodes.Clear();
582         }
583
584         private void btnRefMergeTso_Click(object sender, EventArgs e)
585         {
586             try
587             {
588                 SaveFileDialog dlg = new SaveFileDialog();
589                 dlg.Filter = "TSO File (*.tso)|*.tso";
590                 dlg.FileName = tbMergeTso.Text;
591
592                 if (dlg.ShowDialog() == DialogResult.OK)
593                     tbMergeTso.Text = dlg.FileName;
594             }
595             catch (Exception exception)
596             {
597                 Util.ProcessError(exception);
598             }
599         }
600
601         public static bool bTvMerge_AfterCheck = false;
602
603         private void tvMerge_AfterCheck(object sender, TreeViewEventArgs e)
604         {
605             if (bTvMerge_AfterCheck)
606                 return;
607
608             bTvMerge_AfterCheck = true;
609
610             try
611             {
612                 if (e.Node.Level == 0)
613                 {
614                     foreach (TreeNode node in e.Node.Nodes)
615                         node.Checked = e.Node.Checked;
616                 }
617                 else
618                 {
619                     bool check = false;
620
621                     foreach (TreeNode node in e.Node.Parent.Nodes)
622                         if (node.Checked) check = true;
623
624                     e.Node.Parent.Checked = check;
625                 }
626             }
627             finally
628             {
629                 bTvMerge_AfterCheck = false;
630             }
631         }
632         #endregion
633     }
634
635     public class Util
636     {
637         public static void ProcessError(Exception exception)
638         {
639             MessageBox.Show(exception.ToString());
640         }
641     }
642 }