OSDN Git Service

#38362 FulAVIの仕様を全面変更。FullAVI改めForceScalingAVIがOnの時に、ScaledAVIX,Y,W,Hで指定した領域に旧AVIをアスペ...
[dtxmania/dtxmania.git] / DTXMania / コード / スコア、曲 / CDTXInput.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Runtime.InteropServices;
5 using System.Drawing;
6 using System.Diagnostics;
7 using System.IO;
8 using System.Security.Cryptography;
9 using System.Reflection;
10 using System.Globalization;
11 using System.Threading;
12 using FDK;
13
14 namespace DTXMania
15 {
16         public partial class CDTX
17         {
18                 public void t入力(string strファイル名, bool bEnumerating, bool bレーン情報を確認する)
19                 {
20                         this.t入力(strファイル名, bEnumerating, bレーン情報を確認する, 1.0, 0);
21                 }
22                 public void t入力(string strファイル名, bool bEnumerating, bool bレーン情報を確認する, double db再生速度, int nBGMAdjust)
23                 {
24                         this.bヘッダのみ = bEnumerating;
25                         this.bレーン情報を確認する = bレーン情報を確認する;
26                         this.strファイル名の絶対パス = Path.GetFullPath(strファイル名);
27                         this.strファイル名 = Path.GetFileName(this.strファイル名の絶対パス);
28                         this.strフォルダ名 = Path.GetDirectoryName(this.strファイル名の絶対パス) + @"\";
29                         string ext = Path.GetExtension(this.strファイル名).ToLower();
30                         if (ext != null)
31                         {
32                                 if (!(ext == ".dtx"))
33                                 {
34                                         if (ext == ".gda")
35                                         {
36                                                 this.e種別 = EDTX種別.GDA;
37                                         }
38                                         else if (ext == ".g2d")
39                                         {
40                                                 this.e種別 = EDTX種別.G2D;
41                                         }
42                                         else if (ext == ".bms")
43                                         {
44                                                 this.e種別 = EDTX種別.BMS;
45                                         }
46                                         else if (ext == ".bme")
47                                         {
48                                                 this.e種別 = EDTX種別.BME;
49                                         }
50                                         else if (ext == ".mid")
51                                         {
52                                                 this.e種別 = EDTX種別.SMF;
53                                         }
54                                 }
55                                 else
56                                 {
57                                         this.e種別 = EDTX種別.DTX;
58                                 }
59                         }
60                         if (this.e種別 != EDTX種別.SMF)
61                         {
62                                 try
63                                 {
64                                         //DateTime timeBeginLoad = DateTime.Now;
65                                         //TimeSpan span;
66
67                                         StreamReader reader = new StreamReader(strファイル名, Encoding.GetEncoding("Shift_JIS"));
68                                         string str2 = reader.ReadToEnd();
69                                         reader.Close();
70                                         //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
71                                         //Trace.TraceInformation( "DTXfileload時間:          {0}", span.ToString() );
72
73                                         this.t入力_全入力文字列から(str2, db再生速度, nBGMAdjust);
74                                 }
75                                 catch
76                                 {
77                                 }
78                         }
79                         else
80                         {
81                                 Trace.TraceWarning("SMF の演奏は未対応です。(検討中)");
82                         }
83                 }
84                 public void t入力_全入力文字列から(string str全入力文字列)
85                 {
86                         this.t入力_全入力文字列から(str全入力文字列, 1.0, 0);
87                 }
88                 public unsafe void t入力_全入力文字列から(string str全入力文字列, double db再生速度, int nBGMAdjust)
89                 {
90                         //DateTime timeBeginLoad = DateTime.Now;
91                         //TimeSpan span;
92
93                         if (!string.IsNullOrEmpty(str全入力文字列))
94                         {
95                                 #region [ 改行カット ]
96                                 this.db再生速度 = db再生速度;
97                                 str全入力文字列 = str全入力文字列.Replace(Environment.NewLine, "\n");
98                                 str全入力文字列 = str全入力文字列.Replace('\t', ' ');
99                                 str全入力文字列 = str全入力文字列 + "\n";
100                                 #endregion
101                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
102                                 //Trace.TraceInformation( "改行カット時間:           {0}", span.ToString() );
103                                 //timeBeginLoad = DateTime.Now;
104                                 #region [ 初期化 ]
105                                 for (int j = 0; j < 36 * 36; j++)
106                                 {
107                                         this.n無限管理WAV[j] = -j;
108                                         this.n無限管理BPM[j] = -j;
109                                         this.n無限管理VOL[j] = -j;
110                                         this.n無限管理PAN[j] = -10000 - j;
111                                         this.n無限管理SIZE[j] = -j;
112                                 }
113                                 this.n内部番号WAV1to = 1;
114                                 this.n内部番号BPM1to = 1;
115                                 this.bstackIFからENDIFをスキップする = new Stack<bool>();
116                                 this.bstackIFからENDIFをスキップする.Push(false);
117                                 this.n現在の乱数 = 0;
118                                 for (int k = 0; k < 7; k++)
119                                 {
120                                         this.nRESULTIMAGE用優先順位[k] = 0;
121                                         this.nRESULTMOVIE用優先順位[k] = 0;
122                                         this.nRESULTSOUND用優先順位[k] = 0;
123                                 }
124                                 #endregion
125                                 #region [ 入力/行解析 ]
126                                 CharEnumerator ce = str全入力文字列.GetEnumerator();
127                                 if (ce.MoveNext())
128                                 {
129                                         this.n現在の行数 = 1;
130                                         do
131                                         {
132                                                 if (!this.t入力_空白と改行をスキップする(ref ce))
133                                                 {
134                                                         break;
135                                                 }
136                                                 if (ce.Current == '#')
137                                                 {
138                                                         if (ce.MoveNext())
139                                                         {
140                                                                 StringBuilder builder = new StringBuilder(0x20);
141                                                                 if (this.t入力_コマンド文字列を抜き出す(ref ce, ref builder))
142                                                                 {
143                                                                         StringBuilder builder2 = new StringBuilder(0x400);
144                                                                         if (this.t入力_パラメータ文字列を抜き出す(ref ce, ref builder2))
145                                                                         {
146                                                                                 StringBuilder builder3 = new StringBuilder(0x400);
147                                                                                 if (this.t入力_コメント文字列を抜き出す(ref ce, ref builder3))
148                                                                                 {
149                                                                                         this.t入力_行解析(ref builder, ref builder2, ref builder3);
150                                                                                         this.n現在の行数++;
151                                                                                         continue;
152                                                                                 }
153                                                                         }
154                                                                 }
155                                                         }
156                                                         break;
157                                                 }
158                                         }
159                                         while (this.t入力_コメントをスキップする(ref ce));
160                                         #endregion
161                                         //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
162                                         //Trace.TraceInformation( "抜き出し時間:             {0}", span.ToString() );
163                                         //timeBeginLoad = DateTime.Now;
164                                         this.n無限管理WAV = null;
165                                         this.n無限管理BPM = null;
166                                         this.n無限管理VOL = null;
167                                         this.n無限管理PAN = null;
168                                         this.n無限管理SIZE = null;
169                                         if (!this.bヘッダのみ && this.bレーン情報を確認する)
170                                         {
171                                                 #region [ BPM/BMP初期化 ]
172                                                 CBPM cbpm = null;
173                                                 foreach (CBPM cbpm2 in this.listBPM.Values)
174                                                 {
175                                                         if (cbpm2.n表記上の番号 == 0)
176                                                         {
177                                                                 cbpm = cbpm2;
178                                                                 break;
179                                                         }
180                                                 }
181                                                 if (cbpm == null)
182                                                 {
183                                                         cbpm = new CBPM();
184                                                         cbpm.n内部番号 = this.n内部番号BPM1to++;
185                                                         cbpm.n表記上の番号 = 0;
186                                                         cbpm.dbBPM値 = 120.0;
187                                                         this.listBPM.Add(cbpm.n内部番号, cbpm);
188                                                         CChip chip = new CChip(0, 0, cbpm.n内部番号, EChannel.BPMEx);
189                                                         this.listChip.Insert(0, chip);
190                                                 }
191                                                 else
192                                                 {
193                                                         CChip chip = new CChip(0, 0, cbpm.n内部番号, EChannel.BPMEx);
194                                                         this.listChip.Insert(0, chip);
195                                                 }
196                                                 if (this.listBMP.ContainsKey(0))
197                                                 {
198                                                         CChip chip = new CChip(0, 0, 0, EChannel.BGALayer1);
199                                                         this.listChip.Insert(0, chip);
200                                                 }
201                                                 #endregion
202                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
203                                                 //Trace.TraceInformation( "前準備完了時間:           {0}", span.ToString() );
204                                                 //timeBeginLoad = DateTime.Now;
205                                                 #region [ CWAV初期化 ]
206                                                 foreach (CWAV cwav in this.listWAV.Values)
207                                                 {
208                                                         if (cwav.nチップサイズ < 0)
209                                                         {
210                                                                 cwav.nチップサイズ = 100;
211                                                         }
212                                                         if (cwav.n位置 <= -10000)
213                                                         {
214                                                                 cwav.n位置 = 0;
215                                                         }
216                                                         if (cwav.n音量 < 0)
217                                                         {
218                                                                 cwav.n音量 = 100;
219                                                         }
220                                                 }
221                                                 #endregion
222                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
223                                                 //Trace.TraceInformation( "CWAV前準備時間:           {0}", span.ToString() );
224                                                 //timeBeginLoad = DateTime.Now;
225                                                 #region [ チップ倍率設定 ]                                               // #28145 2012.4.22 yyagi 二重ループを1重ループに変更して高速化)
226                                                 //foreach ( CWAV cwav in this.listWAV.Values )
227                                                 //{
228                                                 //    foreach( CChip chip in this.listChip )
229                                                 //    {
230                                                 //        if( chip.n整数値・内部番号 == cwav.n内部番号 )
231                                                 //        {
232                                                 //            chip.dbチップサイズ倍率 = ( (double) cwav.nチップサイズ ) / 100.0;
233                                                 //            if (chip.nチャンネル番号 == 0x01 ) // BGMだったら
234                                                 //            {
235                                                 //                cwav.bIsOnBGMLane = true;
236                                                 //            }
237                                                 //        }
238                                                 //    }
239                                                 //}
240                                                 foreach (CChip chip in this.listChip)
241                                                 {
242                                                         if (this.listWAV.ContainsKey(chip.n整数値_内部番号))
243                                                         //foreach ( CWAV cwav in this.listWAV.Values )
244                                                         {
245                                                                 CWAV cwav = this.listWAV[chip.n整数値_内部番号];
246                                                                 //      if ( chip.n整数値・内部番号 == cwav.n内部番号 )
247                                                                 //      {
248                                                                 chip.SetDBChipSizeFactor(((double)cwav.nチップサイズ) / 100.0);
249                                                                 //if ( chip.nチャンネル番号 == 0x01 )    // BGMだったら
250                                                                 //{
251                                                                 //      cwav.bIsOnBGMLane = true;
252                                                                 //}
253                                                                 //      }
254                                                         }
255                                                 }
256                                                 #endregion
257                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
258                                                 //Trace.TraceInformation( "CWAV全準備時間:           {0}", span.ToString() );
259                                                 //timeBeginLoad = DateTime.Now;
260                                                 #region [ 必要に応じて空打ち音を0小節に定義する ]
261                                                 //for ( int m = 0xb1; m <= 0xbc; m++ )                  // #28146 2012.4.21 yyagi; bb -> bc
262                                                 //{
263                                                 //    foreach ( CChip chip in this.listChip )
264                                                 //    {
265                                                 //        if ( chip.nチャンネル番号 == m )
266                                                 //        {
267                                                 //            CChip c = new CChip();
268                                                 //            c.n発声位置 = 0;
269                                                 //            c.nチャンネル番号 = chip.nチャンネル番号;
270                                                 //            c.n整数値 = chip.n整数値;
271                                                 //            c.n整数値・内部番号 = chip.n整数値・内部番号;
272                                                 //            this.listChip.Insert( 0, c );
273                                                 //            break;
274                                                 //        }
275                                                 //    }
276                                                 //}
277                                                 #endregion
278                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
279                                                 //Trace.TraceInformation( "空打確認時間:             {0}", span.ToString() );
280                                                 //timeBeginLoad = DateTime.Now;
281                                                 #region [ 拍子・拍線の挿入と、クリック音の挿入と、最初に再生するサウンド直前へのマーカー挿入(録音開始トリガ) ]
282                                                 if (this.listChip.Count > 0)
283                                                 {
284                                                         this.listChip.Sort();   // 高速化のためにはこれを削りたいが、listChipの最後がn発声位置の終端である必要があるので、
285                                                                                                                                                         // 保守性確保を優先してここでのソートは残しておく
286                                                                                                                                                         // なお、093時点では、このソートを削除しても動作するようにはしてある。
287                                                                                                                                                         // (ここまでの一部チップ登録を、listChip.Add(c)から同Insert(0,c)に変更してある)
288                                                                                                                                                         // これにより、数ms程度ながらここでのソートも高速化されている。
289                                                         double barlength = 1.0;
290                                                         int nEndOfSong = (this.listChip[this.listChip.Count - 1].n発声位置 + 384) - (this.listChip[this.listChip.Count - 1].n発声位置 % 384);
291                                                         bool bClickOffBeat = (CDTXMania.Instance.ConfigIni.eClickType == EClickType.OffBeat);           // 裏拍でメトロノーム再生
292                                                         for (int tick384 = 0; tick384 <= nEndOfSong; tick384 += 384)  // 小節線の挿入 (後に出てくる拍子線とループをまとめようとするなら、forループの終了条件の微妙な違いに注意が必要)
293                                                         {
294                                                                 CChip chip = new CChip(tick384, 36 * 36 - 1, EChannel.BarLine);
295                                                                 this.listChip.Add(chip);
296                                                         }
297                                                         //this.listChip.Sort();                         // ここでのソートは不要。ただし最後にソートすること
298                                                         int nChipNo_BarLength = 0;
299                                                         int nChipNo_C1 = 0;
300                                                         for (int tick384 = 0; tick384 < nEndOfSong; tick384 += 384)
301                                                         {
302                                                                 int n発声位置_C1_同一小節内 = 0;
303                                                                 while ((nChipNo_C1 < this.listChip.Count) && (this.listChip[nChipNo_C1].n発声位置 < (tick384 + 384)))
304                                                                 {
305                                                                         if (this.listChip[nChipNo_C1].eチャンネル番号 == EChannel.BeatLineShift)       // 拍線シフトの検出
306                                                                         {
307                                                                                 n発声位置_C1_同一小節内 = this.listChip[nChipNo_C1].n発声位置 - tick384;
308                                                                         }
309                                                                         nChipNo_C1++;
310                                                                 }
311                                                                 if ((this.e種別 == EDTX種別.BMS) || (this.e種別 == EDTX種別.BME))
312                                                                 {
313                                                                         barlength = 1.0;
314                                                                 }
315                                                                 while ((nChipNo_BarLength < this.listChip.Count) && (this.listChip[nChipNo_BarLength].n発声位置 <= tick384))
316                                                                 {
317                                                                         if (this.listChip[nChipNo_BarLength].eチャンネル番号 == EChannel.BarLength)    // bar lengthの検出
318                                                                         {
319                                                                                 barlength = this.listChip[nChipNo_BarLength].db実数値;
320                                                                         }
321                                                                         nChipNo_BarLength++;
322                                                                 }
323
324                                                                 // 小節線上のクリック音の挿入
325                                                                 int deltaOffBeat = (int) ( 384.0 / 8 / barlength );
326                                                                 if ( !bClickOffBeat )                                                                                                                           // 裏拍でのメトロノーム再生の設定でなければ(Off設定であっても)
327                                                                 {
328                                                                         this.listChip.Add( new CChip( tick384, 1, EChannel.Click ) );                                   // 小節線上に、表拍のクリック音を挿入
329                                                                 }
330                                                                 else if ( tick384 + 384 / 8 <= nEndOfSong )                                                                                     // 裏拍設定で、かつ曲長内に収まるなら
331                                                                 {
332                                                                         this.listChip.Add( new CChip( tick384 + deltaOffBeat, 1, EChannel.Click ) );    // 小節線から8分音符だけ後に、裏拍のクリック音を挿入
333                                                                 }
334
335
336                                                                 for (int i = 0; i < 100; i++)               // 拍線の挿入
337                                                                 {
338                                                                         int tickBeat = (int)(((double)(384 * i)) / (4.0 * barlength));
339                                                                         if ((tickBeat + n発声位置_C1_同一小節内) >= 384)
340                                                                         {
341                                                                                 break;
342                                                                         }
343                                                                         if (((tickBeat + n発声位置_C1_同一小節内) % 384) != 0)
344                                                                         {
345                                                                                 CChip chip = new CChip(tick384 + (tickBeat + n発声位置_C1_同一小節内), 36 * 36 - 1, EChannel.BeatLine);
346                                                                                 this.listChip.Add(chip);
347                                                                                 if ( !bClickOffBeat )                   // メトロノーム設定が裏拍設定でなければ、拍音を挿入
348                                                                                 {
349                                                                                         this.listChip.Add( new CChip( tick384 + ( tickBeat + n発声位置_C1_同一小節内 ), 2, EChannel.Click ) );
350                                                                                 }
351                                                                                 else if ( ( tickBeat + deltaOffBeat + n発声位置_C1_同一小節内 ) < 384 )        // 裏拍設定、かつ小節内に収まっていれば、拍音を挿入
352                                                                                 {
353                                                                                         this.listChip.Add( new CChip( tick384 + ( tickBeat + deltaOffBeat + n発声位置_C1_同一小節内 ), 2, EChannel.Click ) );
354                                                                                 }
355                                                                                 
356                                                                         }
357                                                                 }
358                                                         }
359
360                                                         // 最初にサウンドの再生を開始するチップの位置に、録音開始トリガのマーカーを挿入
361                                                         for (int i = 0; i < listChip.Count; i++)
362                                                         {
363                                                                 if (listChip[i].bWAVを使うチャンネルである)
364                                                                 {
365                                                                         int playPosition = listChip[i].n発声位置;
366                                                                         CChip chip = new CChip(playPosition, 36 * 36 - 1, EChannel.FirstSoundChip);
367                                                                         this.listChip.Insert(i, chip);
368                                                                         break;
369                                                                 }
370                                                         }
371
372                                                         this.listChip.Sort();
373                                                 }
374                                                 #endregion
375                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
376                                                 //Trace.TraceInformation( "拍子・拍線挿入時間:       {0}", span.ToString() );
377                                                 //timeBeginLoad = DateTime.Now;
378                                                 #region [ C2 [拍線・小節線表示指定] の処理 ]               // #28145 2012.4.21 yyagi; 2重ループをほぼ1重にして高速化
379                                                 bool bShowBeatBarLine = true;
380                                                 for (int i = 0; i < this.listChip.Count; i++)
381                                                 {
382                                                         bool bChangedBeatBarStatus = false;
383                                                         if ((this.listChip[i].eチャンネル番号 == EChannel.BeatLineDisplay))
384                                                         {
385                                                                 if (this.listChip[i].n整数値 == 1)       // BAR/BEAT LINE = ON
386                                                                 {
387                                                                         bShowBeatBarLine = true;
388                                                                         bChangedBeatBarStatus = true;
389                                                                 }
390                                                                 else if (this.listChip[i].n整数値 == 2)      // BAR/BEAT LINE = OFF
391                                                                 {
392                                                                         bShowBeatBarLine = false;
393                                                                         bChangedBeatBarStatus = true;
394                                                                 }
395                                                         }
396                                                         int startIndex = i;
397                                                         if (bChangedBeatBarStatus)              // C2チップの前に50/51チップが来ている可能性に配慮
398                                                         {
399                                                                 while (startIndex > 0 && this.listChip[startIndex].n発声位置 == this.listChip[i].n発声位置)
400                                                                 {
401                                                                         startIndex--;
402                                                                 }
403                                                                 startIndex++; // 1つ小さく過ぎているので、戻す
404                                                         }
405                                                         for (int j = startIndex; j <= i; j++)
406                                                         {
407                                                                 if (((this.listChip[j].eチャンネル番号 == EChannel.BarLine) || (this.listChip[j].eチャンネル番号 == EChannel.BeatLine)) &&
408                                                                         (this.listChip[j].n整数値 == (36 * 36 - 1)))
409                                                                 {
410                                                                         this.listChip[j].b可視 = bShowBeatBarLine;
411                                                                 }
412                                                         }
413                                                 }
414                                                 #endregion
415                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
416                                                 //Trace.TraceInformation( "C2 [拍線・小節線表示指定]:  {0}", span.ToString() );
417                                                 //timeBeginLoad = DateTime.Now;
418                                                 #region [ 発声時刻の計算 ]
419                                                 double bpm = 120.0;
420                                                 double dbBarLength = 1.0;
421                                                 int nPlayPosition = 0;
422                                                 int ms = 0;
423                                                 int nBar = 0;
424                                                 foreach (CChip chip in this.listChip)
425                                                 {
426                                                         chip.CalculatePlayPositionMs(e種別, BASEBPM, listBPM, listAVIPAN, listBGAPAN,
427                                                                 ref bpm, ref dbBarLength, ref nPlayPosition, ref ms, ref nBar);
428                                                 }
429                                                 if (this.db再生速度 > 0.0)
430                                                 {
431                                                         double _db再生速度 = (CDTXMania.Instance.DTXVmode.Enabled) ? this.dbDTXVPlaySpeed : this.db再生速度;
432                                                         foreach (CChip chip in this.listChip)
433                                                         {
434                                                                 chip.ApplyPlaySpeed(_db再生速度);
435                                                         }
436                                                 }
437                                                 #endregion
438                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
439                                                 //Trace.TraceInformation( "発声時刻計算:             {0}", span.ToString() );
440                                                 //timeBeginLoad = DateTime.Now;
441                                                 this.nBGMAdjust = 0;
442                                                 this.t各自動再生音チップの再生時刻を変更する(nBGMAdjust);
443                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
444                                                 //Trace.TraceInformation( "再生時刻変更:             {0}", span.ToString() );
445                                                 //timeBeginLoad = DateTime.Now;
446                                                 #region [ 可視チップ数カウント ]
447                                                 for (EPart inst = EPart.Drums; inst <= EPart.Bass; ++inst)
448                                                 {
449                                                         this.n可視チップ数[inst] = 0;
450                                                 }
451                                                 foreach (CChip chip in this.listChip)
452                                                 {
453                                                         if (chip.bDrums可視チップ && !chip.b空打ちチップである)
454                                                         {
455                                                                 this.n可視チップ数.Drums++;
456                                                         }
457                                                         if (chip.bGuitar可視チップ)
458                                                         {
459                                                                 this.n可視チップ数.Guitar++;
460                                                         }
461                                                         if (chip.bBass可視チップ)
462                                                         {
463                                                                 this.n可視チップ数.Bass++;
464                                                         }
465                                                 }
466                                                 #endregion
467                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
468                                                 //Trace.TraceInformation( "可視チップ数カウント      {0}", span.ToString() );
469                                                 //timeBeginLoad = DateTime.Now;
470                                                 #region [ チップの種類を分類し、対応するフラグを立てる ]
471                                                 foreach (CChip chip in this.listChip)
472                                                 {
473                                                         if ((
474                                                                 chip.bWAVを使うチャンネルである &&
475                                                                 this.listWAV.ContainsKey(chip.n整数値_内部番号)) &&
476                                                                 !this.listWAV[chip.n整数値_内部番号].listこのWAVを使用するチャンネル番号の集合.Contains(chip.eチャンネル番号))
477                                                         {
478                                                                 this.listWAV[chip.n整数値_内部番号].listこのWAVを使用するチャンネル番号の集合.Add(chip.eチャンネル番号);
479
480                                                                 switch (chip.ESoundChipTypeを得る)
481                                                                 {
482                                                                         case ESoundChipType.Drums:
483                                                                                 if (!chip.b空打ちチップである)
484                                                                                 {
485                                                                                         this.listWAV[chip.n整数値_内部番号].bIsDrumsSound = true;
486                                                                                 }
487                                                                                 break;
488                                                                         case ESoundChipType.Guitar:
489                                                                                 this.listWAV[chip.n整数値_内部番号].bIsGuitarSound = true; break;
490                                                                         case ESoundChipType.Bass:
491                                                                                 this.listWAV[chip.n整数値_内部番号].bIsBassSound = true; break;
492                                                                         case ESoundChipType.SE:
493                                                                                 this.listWAV[chip.n整数値_内部番号].bIsSESound = true; break;
494                                                                         case ESoundChipType.BGM:
495                                                                                 this.listWAV[chip.n整数値_内部番号].bIsBGMSound = true; break;
496                                                                 }
497                                                         }
498                                                 }
499                                                 #endregion
500                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
501                                                 //Trace.TraceInformation( "ch番号集合確認:           {0}", span.ToString() );
502                                                 //timeBeginLoad = DateTime.Now;
503                                                 #region [ hash値計算 ]
504                                                 byte[] buffer = null;
505                                                 try
506                                                 {
507                                                         FileStream stream = new FileStream(this.strファイル名の絶対パス, FileMode.Open, FileAccess.Read);
508                                                         buffer = new byte[stream.Length];
509                                                         stream.Read(buffer, 0, (int)stream.Length);
510                                                         stream.Close();
511                                                 }
512                                                 catch (Exception exception)
513                                                 {
514                                                         Trace.TraceError(exception.Message);
515                                                         Trace.TraceError("DTXのハッシュの計算に失敗しました。({0})", this.strファイル名の絶対パス);
516                                                 }
517                                                 if (buffer != null)
518                                                 {
519                                                         byte[] buffer2 = new MD5CryptoServiceProvider().ComputeHash(buffer);
520                                                         StringBuilder sb = new StringBuilder();
521                                                         foreach (byte b in buffer2)
522                                                         {
523                                                                 sb.Append(b.ToString("x2"));
524                                                         }
525                                                         this.strハッシュofDTXファイル = sb.ToString();
526                                                 }
527                                                 else
528                                                 {
529                                                         this.strハッシュofDTXファイル = "00000000000000000000000000000000";
530                                                 }
531                                                 #endregion
532
533                                                 // #36177 使用レーン数の表示 add ikanick 16.03.20
534                                                 #region [ 使用レーン数カウント ]
535
536                                                 for (EPart inst = EPart.Drums; inst <= EPart.Bass; ++inst)
537                                                 {
538                                                         this.n使用レーン数[inst] = EUseLanes.Other;
539                                                 }
540                                                 foreach (CChip chip in this.listChip)
541                                                 {
542                                                         int ch = (int)chip.eチャンネル番号;
543                                                         if (chip.bDrums可視チップ)
544                                                         {
545                                                                 if (this.n使用レーン数.Drums == EUseLanes.Other) this.n使用レーン数.Drums = EUseLanes.Dr_6;
546                                                                 if ( ( this.n使用レーン数.Drums != EUseLanes.Dr_10 ) && ( this.n使用レーン数.Drums != EUseLanes.Dr_12 ) )
547                                                                 {
548                                                                         if ((chip.eチャンネル番号 == EChannel.FloorTom)
549                                                                         || (chip.eチャンネル番号 == EChannel.HiHatOpen)
550                                                                         || (chip.eチャンネル番号 == EChannel.RideCymbal)
551                                                                         || (chip.eチャンネル番号 == EChannel.LeftCymbal))
552                                                                         {
553                                                                                 this.n使用レーン数.Drums = EUseLanes.Dr_10;
554                                                                         }
555                                                                 }
556                                                                 if (this.n使用レーン数.Drums != EUseLanes.Dr_12)
557                                                                 {
558                                                                         if ((chip.eチャンネル番号 == EChannel.LeftPedal)
559                                                                         || (chip.eチャンネル番号 == EChannel.LeftBassDrum))
560                                                                         {
561                                                                                 this.n使用レーン数.Drums = EUseLanes.Dr_12;
562                                                                         }
563                                                                 }
564                                                         }
565                                                         if (chip.bGuitar可視チップ)
566                                                         {
567                                                                 // 5レーン未対応
568                                                                 if ( this.n使用レーン数.Guitar == EUseLanes.Other ) this.n使用レーン数.Guitar = EUseLanes.GB_3;
569                                                         }
570                                                         if (chip.bBass可視チップ)
571                                                         {
572                                                                 // 5レーン未対応
573                                                                 if ( this.n使用レーン数.Bass == EUseLanes.Other ) this.n使用レーン数.Bass = EUseLanes.GB_3;
574                                                         }
575                                                 }
576                                                 //Trace.TraceInformation( "LeftPedal使用=" + this.bチップがある.LeftPedal );
577                                                 //Trace.TraceInformation( "LeftBass使用 =" + this.bチップがある.LeftBassDrum );
578                                                 //Trace.TraceInformation( "Lane Type    =" + this.n使用レーン数.Drums );
579                                                 #endregion
580
581                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );
582                                                 //Trace.TraceInformation( "hash計算:                 {0}", span.ToString() );
583                                                 //timeBeginLoad = DateTime.Now;
584                                                 #region [ bLogDTX詳細ログ出力 ]
585                                                 if (CDTXMania.Instance.ConfigIni.bLogDTX)
586                                                 {
587                                                         foreach (CWAV cwav in this.listWAV.Values)
588                                                         {
589                                                                 Trace.TraceInformation(cwav.ToString());
590                                                         }
591                                                         foreach (CAVI cavi in this.listAVI.Values)
592                                                         {
593                                                                 Trace.TraceInformation(cavi.ToString());
594                                                         }
595                                                         foreach (CAVIPAN cavipan in this.listAVIPAN.Values)
596                                                         {
597                                                                 Trace.TraceInformation(cavipan.ToString());
598                                                         }
599                                                         foreach (CBGA cbga in this.listBGA.Values)
600                                                         {
601                                                                 Trace.TraceInformation(cbga.ToString());
602                                                         }
603                                                         foreach (CBGAPAN cbgapan in this.listBGAPAN.Values)
604                                                         {
605                                                                 Trace.TraceInformation(cbgapan.ToString());
606                                                         }
607                                                         foreach (CBMP cbmp in this.listBMP.Values)
608                                                         {
609                                                                 Trace.TraceInformation(cbmp.ToString());
610                                                         }
611                                                         foreach (CBMPTEX cbmptex in this.listBMPTEX.Values)
612                                                         {
613                                                                 Trace.TraceInformation(cbmptex.ToString());
614                                                         }
615                                                         foreach (CBPM cbpm3 in this.listBPM.Values)
616                                                         {
617                                                                 Trace.TraceInformation(cbpm3.ToString());
618                                                         }
619                                                         foreach (CChip chip in this.listChip)
620                                                         {
621                                                                 Trace.TraceInformation(chip.ToString());
622                                                         }
623                                                 }
624                                                 #endregion
625
626
627                                         }
628                                 }
629                         }
630                 }
631
632                 /// <summary>
633                 /// #34016 LP/LBD使用譜面の吸収
634                 /// </summary>
635                 public void ReassignLP()
636                 {
637                         if ( this.bチップがある.LeftPedal )
638                         {
639                                 if ( this.bチップがある.LeftBassDrum )
640                                 {       // LP かつ LBDがある場合
641                                         // → * LBDはBDに割り当て
642                                         //    * LPは、HO(foot splash)に割り当て。あるいは、HO(foot splash)とHC(close)のいずれかに割り当てる。
643                                         //      BPMから4分音符の長さを計算し、それより長いかどうかでHO/HCの仕分けを決定。 
644                                         //    * チップ音にサウンドファイルが割り当てられていない場合は、HCに割り当て 
645                                         //    * HO未使用の譜面の場合は、HCに割り当て
646
647                                         double bpm = this.BPM + this.BASEBPM;
648                                         double dbBarLength = 1.0;
649                                         double nLen4thNoteMs = (int) ( ( 60.0 / bpm / dbBarLength ) * 10 * 10 * 10 );
650
651                                         for ( int i = 0; i < this.listChip.Count; i++ )
652                                         {
653                                                 // switch-caseにすると、listchip[i]の書き換えができないので、if-elseで記述
654                                                 if ( this.listChip[ i ].eチャンネル番号 == EChannel.LeftBassDrum )
655                                                 {
656                                                         this.listChip[ i ].eチャンネル番号 = EChannel.BassDrum;
657                                                 }
658                                                 else if ( this.listChip[ i ].eチャンネル番号 == EChannel.LeftPedal )
659                                                 {
660                                                         int len = this.listChip[ i ].GetDuration();             // WAV未割当の場合は0が返る
661                                                                                                                                                         // HHOpen未使用の譜面であれば、無条件にHHCloseに落としこむ
662                                                         this.listChip[ i ].eチャンネル番号 = ( len < nLen4thNoteMs || !this.bチップがある.HHOpen ) ? EChannel.HiHatClose : EChannel.HiHatOpen;
663                                                 }
664                                                 else if ( this.listChip[ i ].eチャンネル番号 == EChannel.BPM )
665                                                 {
666                                                         bpm = this.BPM + this.BASEBPM;
667                                                         nLen4thNoteMs = (int) ( ( 60.0 / bpm / dbBarLength / 2 ) * 10 * 10 * 10 );
668                                                 }
669                                                 else if ( this.listChip[ i ].eチャンネル番号 == EChannel.BPMEx )
670                                                 {
671                                                         int n内部番号 = listChip[ i ].n整数値_内部番号;
672                                                         if ( listBPM.ContainsKey( n内部番号 ) )
673                                                         {
674                                                                 bpm = ( ( listBPM[ n内部番号 ].n表記上の番号 == 0 ) ? 0.0 : this.BASEBPM ) + listBPM[ n内部番号 ].dbBPM値;
675                                                         }
676                                                 }
677                                                 else if ( this.listChip[ i ].eチャンネル番号 == EChannel.BarLength )
678                                                 {
679                                                         dbBarLength = this.listChip[ i ].db実数値;
680                                                 }
681                                         }
682                                 }
683                                 else
684                                 {       // LPしかない場合
685                                         // → LPを、BD, HO, HCに割り当てる必要がある。
686                                         //    * BDへの割り当ては、BDレーンで同じ音を使っているかどうかで決定 
687                                         //    * HO, HCへの割り当ては、(BDの可能性を除いた後) HOにアサイン、あるいはチップの長さを見てHC/HOにアサイン
688                                         //    * チップ音にサウンドファイルが割り当てられていない場合は、HCに割り当て 
689                                         //    * HO未使用の譜面の場合は、HCに割り当て
690
691                                         double bpm = this.BPM + this.BASEBPM;
692                                         double dbBarLength = 1.0;
693                                         double nLen4thNoteMs = (int) ( ( 60.0 / bpm / dbBarLength ) * 10 * 10 * 10 );
694
695                                         #region [ BassDrumのファイル名一覧を作成 ]
696                                         List<string> listBDFilenames = new List<string>();
697                                         foreach ( CChip chip in listChip )
698                                         {
699                                                 if (chip.eチャンネル番号 == EChannel.BassDrum)
700                                                 {
701                                                         string s = chip.GetSoundFilename();
702                                                         if (s != null && !listBDFilenames.Contains(s))
703                                                         {
704                                                                 listBDFilenames.Add(s);
705                                                         }
706                                                 }
707                                         }
708                                         #endregion
709
710                                         for ( int i = 0; i < this.listChip.Count; i++ )
711                                         {
712                                                 if ( this.listChip[ i ].eチャンネル番号 == EChannel.LeftPedal )
713                                                 {
714                                                         string s = listChip[i].GetSoundFilename();
715                                                         if (listBDFilenames.Contains(s))
716                                                         {
717                                                                 this.listChip[i].eチャンネル番号 = EChannel.BassDrum;
718                                                         }
719                                                         else
720                                                         {
721                                                                 int len = this.listChip[ i ].GetDuration();             // WAV未割当の場合は0が返る
722                                                                                                                                                                 // HHOpen未使用の譜面であれば、無条件にHHCloseに落としこむ
723                                                                 this.listChip[ i ].eチャンネル番号 = ( len < nLen4thNoteMs || !this.bチップがある.HHOpen ) ? EChannel.HiHatClose : EChannel.HiHatOpen;
724                                                         }
725                                                 }
726                                                 else if ( this.listChip[ i ].eチャンネル番号 == EChannel.BPM )
727                                                 {
728                                                         bpm = this.BPM + this.BASEBPM;
729                                                         nLen4thNoteMs = (int) ( ( 60.0 / bpm / dbBarLength / 2 ) * 10 * 10 * 10 );
730                                                 }
731                                                 else if ( this.listChip[ i ].eチャンネル番号 == EChannel.BPMEx )
732                                                 {
733                                                         int n内部番号 = listChip[ i ].n整数値_内部番号;
734                                                         if ( listBPM.ContainsKey( n内部番号 ) )
735                                                         {
736                                                                 bpm = ( ( listBPM[ n内部番号 ].n表記上の番号 == 0 ) ? 0.0 : this.BASEBPM ) + listBPM[ n内部番号 ].dbBPM値;
737                                                         }
738                                                 }
739                                                 else if ( this.listChip[ i ].eチャンネル番号 == EChannel.BarLength )
740                                                 {
741                                                         dbBarLength = this.listChip[ i ].db実数値;
742                                                 }
743                                         }
744                                         listBDFilenames.Clear();
745                                         listBDFilenames = null;
746                                 }
747                         }
748                         else if ( this.bチップがある.LeftBassDrum )
749                         {       // LBDのみがある場合
750                                 // → そのままBDに割り当て
751                                 for ( int i = 0; i < this.listChip.Count; i++ )
752                                 {
753                                         if ( this.listChip[ i ].eチャンネル番号 == EChannel.LeftBassDrum )
754                                         {
755                                                 this.listChip[ i ].eチャンネル番号 = EChannel.BassDrum;
756                                         }
757                                 }
758                         }
759                         else
760                         {       // LPもLBDもない場合
761                                 // → 何もしない
762                         }
763                 }
764                 private bool t入力_コマンド文字列を抜き出す(ref CharEnumerator ce, ref StringBuilder sb文字列)
765                 {
766                         if (!this.t入力_空白をスキップする(ref ce))
767                                 return false; // 文字が尽きた
768
769                         #region [ コマンド終端文字(':')、半角空白、コメント開始文字(';')、改行のいずれかが出現するまでをコマンド文字列と見なし、sb文字列 にコピーする。]
770                         //-----------------
771                         while (ce.Current != ':' && ce.Current != ' ' && ce.Current != ';' && ce.Current != '\n')
772                         {
773                                 sb文字列.Append(ce.Current);
774
775                                 if (!ce.MoveNext())
776                                         return false; // 文字が尽きた
777                         }
778                         //-----------------
779                         #endregion
780
781                         #region [ コマンド終端文字(':')で終端したなら、その次から空白をスキップしておく。]
782                         //-----------------
783                         if (ce.Current == ':')
784                         {
785                                 if (!ce.MoveNext())
786                                         return false; // 文字が尽きた
787
788                                 if (!this.t入力_空白をスキップする(ref ce))
789                                         return false; // 文字が尽きた
790                         }
791                         //-----------------
792                         #endregion
793
794                         return true;
795                 }
796                 private bool t入力_コメントをスキップする(ref CharEnumerator ce)
797                 {
798                         // 改行が現れるまでをコメントと見なしてスキップする。
799
800                         while (ce.Current != '\n')
801                         {
802                                 if (!ce.MoveNext())
803                                         return false; // 文字が尽きた
804                         }
805
806                         // 改行の次の文字へ移動した結果を返す。
807
808                         return ce.MoveNext();
809                 }
810                 private bool t入力_コメント文字列を抜き出す(ref CharEnumerator ce, ref StringBuilder sb文字列)
811                 {
812                         if (ce.Current != ';')    // コメント開始文字(';')じゃなければ正常帰還。
813                                 return true;
814
815                         if (!ce.MoveNext())   // ';' の次で文字列が終わってたら終了帰還。
816                                 return false;
817
818                         #region [ ';' の次の文字から '\n' の1つ前までをコメント文字列と見なし、sb文字列にコピーする。]
819                         //-----------------
820                         while (ce.Current != '\n')
821                         {
822                                 sb文字列.Append(ce.Current);
823
824                                 if (!ce.MoveNext())
825                                         return false;
826                         }
827                         //-----------------
828                         #endregion
829
830                         return true;
831                 }
832                 private void t入力_パラメータ食い込みチェック(string strコマンド名, ref string strコマンド, ref string strパラメータ)
833                 {
834                         if ((strコマンド.Length > strコマンド名.Length) && strコマンド.StartsWith(strコマンド名, StringComparison.OrdinalIgnoreCase))
835                         {
836                                 strパラメータ = strコマンド.Substring(strコマンド名.Length).Trim();
837                                 strコマンド = strコマンド.Substring(0, strコマンド名.Length);
838                         }
839                 }
840                 private bool t入力_パラメータ文字列を抜き出す(ref CharEnumerator ce, ref StringBuilder sb文字列)
841                 {
842                         if (!this.t入力_空白をスキップする(ref ce))
843                                 return false; // 文字が尽きた
844
845                         #region [ 改行またはコメント開始文字(';')が出現するまでをパラメータ文字列と見なし、sb文字列 にコピーする。]
846                         //-----------------
847                         while (ce.Current != '\n' && ce.Current != ';')
848                         {
849                                 sb文字列.Append(ce.Current);
850
851                                 if (!ce.MoveNext())
852                                         return false;
853                         }
854                         //-----------------
855                         #endregion
856
857                         return true;
858                 }
859                 private bool t入力_空白と改行をスキップする(ref CharEnumerator ce)
860                 {
861                         // 空白と改行が続く間はこれらをスキップする。
862
863                         while (ce.Current == ' ' || ce.Current == '\n')
864                         {
865                                 if (ce.Current == '\n')
866                                         this.n現在の行数++;    // 改行文字では行番号が増える。
867
868                                 if (!ce.MoveNext())
869                                         return false; // 文字が尽きた
870                         }
871
872                         return true;
873                 }
874                 private bool t入力_空白をスキップする(ref CharEnumerator ce)
875                 {
876                         // 空白が続く間はこれをスキップする。
877
878                         while (ce.Current == ' ')
879                         {
880                                 if (!ce.MoveNext())
881                                         return false; // 文字が尽きた
882                         }
883
884                         return true;
885                 }
886                 private void t入力_行解析(ref StringBuilder sbコマンド, ref StringBuilder sbパラメータ, ref StringBuilder sbコメント)
887                 {
888                         string strコマンド = sbコマンド.ToString();
889                         string strパラメータ = sbパラメータ.ToString().Trim();
890                         string strコメント = sbコメント.ToString();
891
892                         // 行頭コマンドの処理
893
894                         #region [ IF ]
895                         //-----------------
896                         if (strコマンド.StartsWith("IF", StringComparison.OrdinalIgnoreCase))
897                         {
898                                 this.t入力_パラメータ食い込みチェック("IF", ref strコマンド, ref strパラメータ);
899
900                                 if (this.bstackIFからENDIFをスキップする.Count == 255)
901                                 {
902                                         Trace.TraceWarning("#IF の入れ子の数が 255 を超えました。この #IF を無視します。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
903                                 }
904                                 else if (this.bstackIFからENDIFをスキップする.Peek())
905                                 {
906                                         this.bstackIFからENDIFをスキップする.Push(true); // 親が true ならその入れ子も問答無用で true 。
907                                 }
908                                 else                          // 親が false なら入れ子はパラメータと乱数を比較して結果を判断する。
909                                 {
910                                         int n数値 = 0;
911
912                                         if (!int.TryParse(strパラメータ, out n数値))
913                                                 n数値 = 1;
914
915                                         this.bstackIFからENDIFをスキップする.Push(n数値 != this.n現在の乱数);   // 乱数と数値が一致したら true 。
916                                 }
917                         }
918                         //-----------------
919                         #endregion
920                         #region [ ENDIF ]
921                         //-----------------
922                         else if (strコマンド.StartsWith("ENDIF", StringComparison.OrdinalIgnoreCase))
923                         {
924                                 this.t入力_パラメータ食い込みチェック("ENDIF", ref strコマンド, ref strパラメータ);
925
926                                 if (this.bstackIFからENDIFをスキップする.Count > 1)
927                                 {
928                                         this.bstackIFからENDIFをスキップする.Pop();    // 入れ子を1つ脱出。
929                                 }
930                                 else
931                                 {
932                                         Trace.TraceWarning("#ENDIF に対応する #IF がありません。この #ENDIF を無視します。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
933                                 }
934                         }
935                         //-----------------
936                         #endregion
937
938                         else if (!this.bstackIFからENDIFをスキップする.Peek())   // IF~ENDIF をスキップするなら以下はすべて無視。
939                         {
940                                 #region [ PATH_WAV ]
941                                 //-----------------
942                                 if (strコマンド.StartsWith("PATH_WAV", StringComparison.OrdinalIgnoreCase))
943                                 {
944                                         this.t入力_パラメータ食い込みチェック("PATH_WAV", ref strコマンド, ref strパラメータ);
945                                         this.PATH_WAV = strパラメータ;
946                                 }
947                                 //-----------------
948                                 #endregion
949                                 #region [ TITLE ]
950                                 //-----------------
951                                 else if (strコマンド.StartsWith("TITLE", StringComparison.OrdinalIgnoreCase))
952                                 {
953                                         this.t入力_パラメータ食い込みチェック("TITLE", ref strコマンド, ref strパラメータ);
954                                         this.TITLE = strパラメータ;
955                                 }
956                                 //-----------------
957                                 #endregion
958                                 #region [ ARTIST ]
959                                 //-----------------
960                                 else if (strコマンド.StartsWith("ARTIST", StringComparison.OrdinalIgnoreCase))
961                                 {
962                                         this.t入力_パラメータ食い込みチェック("ARTIST", ref strコマンド, ref strパラメータ);
963                                         this.ARTIST = strパラメータ;
964                                 }
965                                 //-----------------
966                                 #endregion
967                                 #region [ COMMENT ]
968                                 //-----------------
969                                 else if (strコマンド.StartsWith("COMMENT", StringComparison.OrdinalIgnoreCase))
970                                 {
971                                         this.t入力_パラメータ食い込みチェック("COMMENT", ref strコマンド, ref strパラメータ);
972                                         this.COMMENT = strパラメータ;
973                                 }
974                                 //-----------------
975                                 #endregion
976                                 #region [ DLEVEL, PLAYLEVEL ]
977                                 //-----------------
978                                 else if (
979                                         strコマンド.StartsWith("DLEVEL", StringComparison.OrdinalIgnoreCase) ||
980                                         strコマンド.StartsWith("PLAYLEVEL", StringComparison.OrdinalIgnoreCase))
981                                 {
982                                         this.t入力_パラメータ食い込みチェック("DLEVEL", ref strコマンド, ref strパラメータ);
983                                         this.t入力_パラメータ食い込みチェック("PLAYLEVEL", ref strコマンド, ref strパラメータ);
984
985                                         int dlevel;
986                                         if (int.TryParse(strパラメータ, out dlevel))
987                                         {
988                                                 this.LEVEL.Drums = Math.Min(Math.Max(dlevel, 0), 100);  // 0~100 に丸める
989                                         }
990                                 }
991                                 //-----------------
992                                 #endregion
993                                 #region [ GLEVEL ]
994                                 //-----------------
995                                 else if (strコマンド.StartsWith("GLEVEL", StringComparison.OrdinalIgnoreCase))
996                                 {
997                                         this.t入力_パラメータ食い込みチェック("GLEVEL", ref strコマンド, ref strパラメータ);
998
999                                         int glevel;
1000                                         if (int.TryParse(strパラメータ, out glevel))
1001                                         {
1002                                                 this.LEVEL.Guitar = Math.Min(Math.Max(glevel, 0), 100);   // 0~100 に丸める
1003                                         }
1004                                 }
1005                                 //-----------------
1006                                 #endregion
1007                                 #region [ BLEVEL ]
1008                                 //-----------------
1009                                 else if (strコマンド.StartsWith("BLEVEL", StringComparison.OrdinalIgnoreCase))
1010                                 {
1011                                         this.t入力_パラメータ食い込みチェック("BLEVEL", ref strコマンド, ref strパラメータ);
1012
1013                                         int blevel;
1014                                         if (int.TryParse(strパラメータ, out blevel))
1015                                         {
1016                                                 this.LEVEL.Bass = Math.Min(Math.Max(blevel, 0), 100);   // 0~100 に丸める
1017                                         }
1018                                 }
1019                                 //-----------------
1020                                 #endregion
1021 #if TEST_NOTEOFFMODE
1022                                 else if (str.StartsWith("SUPRESSNOTEOFF_HIHAT", StringComparison.OrdinalIgnoreCase)) {
1023                                         this.t入力・パラメータ食い込みチェック("SUPRESSNOTEOFF_HIHAT", ref str, ref str2);
1024                                         this.bHH演奏で直前のHHを消音する = !str2.ToLower().Equals("on");
1025                                 } 
1026                                 else if (str.StartsWith("SUPRESSNOTEOFF_GUITAR", StringComparison.OrdinalIgnoreCase)) {
1027                                         this.t入力・パラメータ食い込みチェック("SUPRESSNOTEOFF_GUITAR", ref str, ref str2);
1028                                         this.bGUITAR演奏で直前のGUITARを消音する = !str2.ToLower().Equals("on");
1029                                 }
1030                                 else if (str.StartsWith("SUPRESSNOTEOFF_BASS", StringComparison.OrdinalIgnoreCase)) {
1031                                         this.t入力・パラメータ食い込みチェック("SUPRESSNOTEOFF_BASS", ref str, ref str2);
1032                                         this.bBASS演奏で直前のBASSを消音する = !str2.ToLower().Equals("on");
1033                                 }
1034 #endif
1035                                 #region [ GENRE ]
1036                                 //-----------------
1037                                 else if (strコマンド.StartsWith("GENRE", StringComparison.OrdinalIgnoreCase))
1038                                 {
1039                                         this.t入力_パラメータ食い込みチェック("GENRE", ref strコマンド, ref strパラメータ);
1040                                         this.GENRE = strパラメータ;
1041                                 }
1042                                 //-----------------
1043                                 #endregion
1044                                 #region [ HIDDENLEVEL ]
1045                                 //-----------------
1046                                 else if (strコマンド.StartsWith("HIDDENLEVEL", StringComparison.OrdinalIgnoreCase))
1047                                 {
1048                                         this.t入力_パラメータ食い込みチェック("HIDDENLEVEL", ref strコマンド, ref strパラメータ);
1049                                         this.HIDDENLEVEL = strパラメータ.ToLower().Equals("on");
1050                                 }
1051                                 //-----------------
1052                                 #endregion
1053                                 #region [ STAGEFILE ]
1054                                 //-----------------
1055                                 else if (strコマンド.StartsWith("STAGEFILE", StringComparison.OrdinalIgnoreCase))
1056                                 {
1057                                         this.t入力_パラメータ食い込みチェック("STAGEFILE", ref strコマンド, ref strパラメータ);
1058                                         this.STAGEFILE = strパラメータ;
1059                                 }
1060                                 //-----------------
1061                                 #endregion
1062                                 #region [ PREVIEW ]
1063                                 //-----------------
1064                                 else if (strコマンド.StartsWith("PREVIEW", StringComparison.OrdinalIgnoreCase))
1065                                 {
1066                                         this.t入力_パラメータ食い込みチェック("PREVIEW", ref strコマンド, ref strパラメータ);
1067                                         this.PREVIEW = strパラメータ;
1068                                 }
1069                                 //-----------------
1070                                 #endregion
1071                                 #region [ PREIMAGE ]
1072                                 //-----------------
1073                                 else if (strコマンド.StartsWith("PREIMAGE", StringComparison.OrdinalIgnoreCase))
1074                                 {
1075                                         this.t入力_パラメータ食い込みチェック("PREIMAGE", ref strコマンド, ref strパラメータ);
1076                                         this.PREIMAGE = strパラメータ;
1077                                 }
1078                                 //-----------------
1079                                 #endregion
1080                                 #region [ PREMOVIE ]
1081                                 //-----------------
1082                                 else if (strコマンド.StartsWith("PREMOVIE", StringComparison.OrdinalIgnoreCase))
1083                                 {
1084                                         this.t入力_パラメータ食い込みチェック("PREMOVIE", ref strコマンド, ref strパラメータ);
1085                                         this.PREMOVIE = strパラメータ;
1086                                 }
1087                                 //-----------------
1088                                 #endregion
1089                                 #region [ USE 556 x 710 BGAAVI ]
1090
1091                                 else if (strコマンド.StartsWith("USE556X710BGAAVI", StringComparison.OrdinalIgnoreCase))
1092                                 {
1093                                         this.t入力_パラメータ食い込みチェック("USE556X710BGAAVI", ref strコマンド, ref strパラメータ);
1094                                         this.bUse556x710BGAAVI = strパラメータ == "1" ? true : false;
1095                                 }
1096                                 #endregion
1097                                 #region [ BACKGROUND_GR ]
1098                                 //-----------------
1099                                 else if (strコマンド.StartsWith("BACKGROUND_GR", StringComparison.OrdinalIgnoreCase))
1100                                 {
1101                                         this.t入力_パラメータ食い込みチェック("BACKGROUND_GR", ref strコマンド, ref strパラメータ);
1102                                         this.BACKGROUND_GR = strパラメータ;
1103                                 }
1104                                 //-----------------
1105                                 #endregion
1106                                 #region [ BACKGROU}ND, WALL ]
1107                                 //-----------------
1108                                 else if (
1109                                         strコマンド.StartsWith("BACKGROUND", StringComparison.OrdinalIgnoreCase) ||
1110                                         strコマンド.StartsWith("WALL", StringComparison.OrdinalIgnoreCase))
1111                                 {
1112                                         this.t入力_パラメータ食い込みチェック("BACKGROUND", ref strコマンド, ref strパラメータ);
1113                                         this.t入力_パラメータ食い込みチェック("WALL", ref strコマンド, ref strパラメータ);
1114                                         this.BACKGROUND = strパラメータ;
1115                                 }
1116                                 //-----------------
1117                                 #endregion
1118                                 #region [ RANDOM ]
1119                                 //-----------------
1120                                 else if (strコマンド.StartsWith("RANDOM", StringComparison.OrdinalIgnoreCase))
1121                                 {
1122                                         this.t入力_パラメータ食い込みチェック("RANDOM", ref strコマンド, ref strパラメータ);
1123
1124                                         int n数値 = 1;
1125                                         if (!int.TryParse(strパラメータ, out n数値))
1126                                                 n数値 = 1;
1127
1128                                         this.n現在の乱数 = CDTXMania.Instance.Random.Next(n数値) + 1;    // 1~数値 までの乱数を生成。
1129                                 }
1130                                 //-----------------
1131                                 #endregion
1132                                 #region [ SOUND_NOWLOADING ]
1133                                 //-----------------
1134                                 else if (strコマンド.StartsWith("SOUND_NOWLOADING", StringComparison.OrdinalIgnoreCase))
1135                                 {
1136                                         this.t入力_パラメータ食い込みチェック("SOUND_NOWLOADING", ref strコマンド, ref strパラメータ);
1137                                         this.SOUND_NOWLOADING = strパラメータ;
1138                                 }
1139                                 //-----------------
1140                                 #endregion
1141                                 #region [ BPM ]
1142                                 //-----------------
1143                                 else if (strコマンド.StartsWith("BPM", StringComparison.OrdinalIgnoreCase))
1144                                 {
1145                                         this.t入力_行解析_BPM_BPMzz(strコマンド, strパラメータ, strコメント);
1146                                 }
1147                                 //-----------------
1148                                 #endregion
1149                                 #region [ DTXVPLAYSPEED ]
1150                                 //-----------------
1151                                 else if (strコマンド.StartsWith("DTXVPLAYSPEED", StringComparison.OrdinalIgnoreCase))
1152                                 {
1153                                         this.t入力_パラメータ食い込みチェック("DTXVPLAYSPEED", ref strコマンド, ref strパラメータ);
1154
1155                                         double dtxvplayspeed = 0.0;
1156                                         if (TryParse(strパラメータ, out dtxvplayspeed) && dtxvplayspeed > 0.0)
1157                                         {
1158                                                 this.dbDTXVPlaySpeed = dtxvplayspeed;
1159                                         }
1160                                 }
1161                                 //-----------------
1162                                 #endregion
1163                                 else if (!this.bヘッダのみ)    // ヘッダのみの解析の場合、以下は無視。
1164                                 {
1165                                         #region [ PANEL ]
1166                                         //-----------------
1167                                         if (strコマンド.StartsWith("PANEL", StringComparison.OrdinalIgnoreCase))
1168                                         {
1169                                                 this.t入力_パラメータ食い込みチェック("PANEL", ref strコマンド, ref strパラメータ);
1170
1171                                                 int dummyResult;                // #23885 2010.12.12 yyagi: not to confuse "#PANEL strings (panel)" and "#PANEL int (panpot of EL)"
1172                                                 if (!int.TryParse(strパラメータ, out dummyResult))
1173                                                 {   // 数値じゃないならPANELとみなす
1174                                                         this.PANEL = strパラメータ;              //
1175                                                         goto EOL;                 //
1176                                                 }                       // 数値ならPAN ELとみなす
1177
1178                                         }
1179                                         //-----------------
1180                                         #endregion
1181                                         #region [ MIDIFILE ]
1182                                         //-----------------
1183                                         else if (strコマンド.StartsWith("MIDIFILE", StringComparison.OrdinalIgnoreCase))
1184                                         {
1185                                                 this.t入力_パラメータ食い込みチェック("MIDIFILE", ref strコマンド, ref strパラメータ);
1186                                                 this.MIDIFILE = strパラメータ;
1187                                         }
1188                                         //-----------------
1189                                         #endregion
1190                                         #region [ MIDINOTE ]
1191                                         //-----------------
1192                                         else if (strコマンド.StartsWith("MIDINOTE", StringComparison.OrdinalIgnoreCase))
1193                                         {
1194                                                 this.t入力_パラメータ食い込みチェック("MIDINOTE", ref strコマンド, ref strパラメータ);
1195                                                 this.MIDINOTE = strパラメータ.ToLower().Equals("on");
1196                                         }
1197                                         //-----------------
1198                                         #endregion
1199                                         #region [ BLACKCOLORKEY ]
1200                                         //-----------------
1201                                         else if (strコマンド.StartsWith("BLACKCOLORKEY", StringComparison.OrdinalIgnoreCase))
1202                                         {
1203                                                 this.t入力_パラメータ食い込みチェック("BLACKCOLORKEY", ref strコマンド, ref strパラメータ);
1204                                                 this.BLACKCOLORKEY = strパラメータ.ToLower().Equals("on");
1205                                         }
1206                                         //-----------------
1207                                         #endregion
1208                                         #region [ BASEBPM ]
1209                                         //-----------------
1210                                         else if (strコマンド.StartsWith("BASEBPM", StringComparison.OrdinalIgnoreCase))
1211                                         {
1212                                                 this.t入力_パラメータ食い込みチェック("BASEBPM", ref strコマンド, ref strパラメータ);
1213
1214                                                 double basebpm = 0.0;
1215                                                 //if( double.TryParse( str2, out num6 ) && ( num6 > 0.0 ) )
1216                                                 if (TryParse(strパラメータ, out basebpm) && basebpm > 0.0) // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point
1217                                                 {                         // #24204 2011.01.21 yyagi: Fix the condition correctly
1218                                                         this.BASEBPM = basebpm;
1219                                                 }
1220                                         }
1221                                         //-----------------
1222                                         #endregion
1223                                         #region [ SOUND_STAGEFAILED ]
1224                                         //-----------------
1225                                         else if (strコマンド.StartsWith("SOUND_STAGEFAILED", StringComparison.OrdinalIgnoreCase))
1226                                         {
1227                                                 this.t入力_パラメータ食い込みチェック("SOUND_STAGEFAILED", ref strコマンド, ref strパラメータ);
1228                                                 this.SOUND_STAGEFAILED = strパラメータ;
1229                                         }
1230                                         //-----------------
1231                                         #endregion
1232                                         #region [ SOUND_FULLCOMBO ]
1233                                         //-----------------
1234                                         else if (strコマンド.StartsWith("SOUND_FULLCOMBO", StringComparison.OrdinalIgnoreCase))
1235                                         {
1236                                                 this.t入力_パラメータ食い込みチェック("SOUND_FULLCOMBO", ref strコマンド, ref strパラメータ);
1237                                                 this.SOUND_FULLCOMBO = strパラメータ;
1238                                         }
1239                                         //-----------------
1240                                         #endregion
1241                                         #region [ SOUND_AUDIENCE ]
1242                                         //-----------------
1243                                         else if (strコマンド.StartsWith("SOUND_AUDIENCE", StringComparison.OrdinalIgnoreCase))
1244                                         {
1245                                                 this.t入力_パラメータ食い込みチェック("SOUND_AUDIENCE", ref strコマンド, ref strパラメータ);
1246                                                 this.SOUND_AUDIENCE = strパラメータ;
1247                                         }
1248                                         //-----------------
1249                                         #endregion
1250
1251                                         // オブジェクト記述コマンドの処理。
1252
1253                                         else if (!this.t入力_行解析_WAVVOL_VOLUME(strコマンド, strパラメータ, strコメント) &&
1254                                                 !this.t入力_行解析_WAVPAN_PAN(strコマンド, strパラメータ, strコメント) &&
1255                                                 !this.t入力_行解析_WAV(strコマンド, strパラメータ, strコメント) &&
1256                                                 !this.t入力_行解析_BMPTEX(strコマンド, strパラメータ, strコメント) &&
1257                                                 !this.t入力_行解析_BMP(strコマンド, strパラメータ, strコメント) &&
1258                                                 !this.t入力_行解析_BGAPAN(strコマンド, strパラメータ, strコメント) &&
1259                                                 !this.t入力_行解析_BGA(strコマンド, strパラメータ, strコメント) &&
1260                                                 !this.t入力_行解析_AVIPAN(strコマンド, strパラメータ, strコメント) &&
1261                                                 !this.t入力_行解析_AVI_VIDEO(strコマンド, strパラメータ, strコメント) &&
1262                                                 //      !this.t入力_行解析_BPM_BPMzz( strコマンド, strパラメータ, strコメント ) &&    // bヘッダのみ==trueの場合でもチェックするよう変更
1263                                                 !this.t入力_行解析_RESULTIMAGE(strコマンド, strパラメータ, strコメント) &&
1264                                                 !this.t入力_行解析_RESULTMOVIE(strコマンド, strパラメータ, strコメント) &&
1265                                                 !this.t入力_行解析_RESULTSOUND(strコマンド, strパラメータ, strコメント) &&
1266                                                 !this.t入力_行解析_SIZE(strコマンド, strパラメータ, strコメント))
1267                                         {
1268                                                 this.t入力_行解析_チップ配置(strコマンド, strパラメータ, strコメント);
1269                                         }
1270                                         EOL:
1271                                         Debug.Assert(true);   // #23885 2010.12.12 yyagi: dummy line to exit parsing the line
1272                                                                                                                                 // 2011.8.17 from: "int xx=0;" から変更。毎回警告が出るので。
1273                                 }
1274                                 //else
1275                                 //{     // Duration測定のため、bヘッダのみ==trueでも、チップ配置は行う
1276                                 //      this.t入力・行解析・チップ配置( strコマンド, strパラメータ, strコメント );
1277                                 //}
1278                         }
1279                 }
1280                 private bool t入力_行解析_AVI_VIDEO(string strコマンド, string strパラメータ, string strコメント)
1281                 {
1282                         // (1) コマンドを処理。
1283
1284                         #region [ "AVI" or "VIDEO" で始まらないコマンドは無効。]
1285                         //-----------------
1286                         if (strコマンド.StartsWith("AVI", StringComparison.OrdinalIgnoreCase))
1287                                 strコマンド = strコマンド.Substring(3);   // strコマンド から先頭の"AVI"文字を除去。
1288
1289                         else if (strコマンド.StartsWith("VIDEO", StringComparison.OrdinalIgnoreCase))
1290                                 strコマンド = strコマンド.Substring(5);   // strコマンド から先頭の"VIDEO"文字を除去。
1291
1292                         else
1293                                 return false;
1294                         //-----------------
1295                         #endregion
1296
1297                         // (2) パラメータを処理。
1298
1299                         if (strコマンド.Length < 2)
1300                                 return false; // AVI番号 zz がないなら無効。
1301
1302                         #region [ AVI番号 zz を取得する。]
1303                         //-----------------
1304                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
1305                         if (zz < 0 || zz >= 36 * 36)
1306                         {
1307                                 Trace.TraceError("AVI(VIDEO)番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
1308                                 return false;
1309                         }
1310                         //-----------------
1311                         #endregion
1312
1313                         #region [ AVIリストに {zz, avi} の組を登録する。 ]
1314                         //-----------------
1315                         var avi = new CAVI(zz, strパラメータ, strコメント, CDTXMania.Instance.ConfigIni.nPlaySpeed);
1316
1317                         if (this.listAVI.ContainsKey(zz)) // 既にリスト中に存在しているなら削除。後のものが有効。
1318                                 this.listAVI.Remove(zz);
1319
1320                         this.listAVI.Add(zz, avi);
1321                         //-----------------
1322                         #endregion
1323
1324                         return true;
1325                 }
1326                 private bool t入力_行解析_AVIPAN(string strコマンド, string strパラメータ, string strコメント)
1327                 {
1328                         // (1) コマンドを処理。
1329
1330                         #region [ "AVIPAN" で始まらないコマンドは無効。]
1331                         //-----------------
1332                         if (!strコマンド.StartsWith("AVIPAN", StringComparison.OrdinalIgnoreCase))
1333                                 return false;
1334
1335                         strコマンド = strコマンド.Substring(6); // strコマンド から先頭の"AVIPAN"文字を除去。
1336                                                                                                                                                         //-----------------
1337                         #endregion
1338
1339                         // (2) パラメータを処理。
1340
1341                         if (strコマンド.Length < 2)
1342                                 return false; // AVIPAN番号 zz がないなら無効。
1343
1344                         #region [ AVIPAN番号 zz を取得する。]
1345                         //-----------------
1346                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
1347                         if (zz < 0 || zz >= 36 * 36)
1348                         {
1349                                 Trace.TraceError("AVIPAN番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
1350                                 return false;
1351                         }
1352                         //-----------------
1353                         #endregion
1354
1355                         var avipan = new CAVIPAN()
1356                         {
1357                                 n番号 = zz,
1358                         };
1359
1360                         // パラメータ引数(14個)を取得し、avipan に登録していく。
1361
1362                         string[] strParams = strパラメータ.Split(new char[] { ' ', ',', '(', ')', '[', ']', 'x', '|' }, StringSplitOptions.RemoveEmptyEntries);
1363
1364                         #region [ パラメータ引数は全14個ないと無効。]
1365                         //-----------------
1366                         if (strParams.Length < 14)
1367                         {
1368                                 Trace.TraceError("AVIPAN: 引数が足りません。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
1369                                 return false;
1370                         }
1371                         //-----------------
1372                         #endregion
1373
1374                         int i = 0;
1375                         int n値 = 0;
1376
1377                         #region [ 1. AVI番号 ]
1378                         //-----------------
1379                         if (string.IsNullOrEmpty(strParams[i]) || strParams[i].Length > 2)
1380                         {
1381                                 Trace.TraceError("AVIPAN: {2}番目の数(AVI番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1382                                 return false;
1383                         }
1384                         avipan.nAVI番号 = C変換.n36進数2桁の文字列を数値に変換して返す(strParams[i]);
1385                         if (avipan.nAVI番号 < 1 || avipan.nAVI番号 >= 36 * 36)
1386                         {
1387                                 Trace.TraceError("AVIPAN: {2}番目の数(AVI番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1388                                 return false;
1389                         }
1390                         i++;
1391                         //-----------------
1392                         #endregion
1393                         #region [ 2. 開始転送サイズ・幅 ]
1394                         //-----------------
1395                         n値 = 0;
1396                         if (!int.TryParse(strParams[i], out n値))
1397                         {
1398                                 Trace.TraceError("AVIPAN: {2}番目の引数(開始転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1399                                 return false;
1400                         }
1401                         avipan.sz開始サイズ.Width = n値;
1402                         i++;
1403                         //-----------------
1404                         #endregion
1405                         #region [ 3. 転送サイズ・高さ ]
1406                         //-----------------
1407                         n値 = 0;
1408                         if (!int.TryParse(strParams[i], out n値))
1409                         {
1410                                 Trace.TraceError("AVIPAN: {2}番目の引数(開始転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1411                                 return false;
1412                         }
1413                         avipan.sz開始サイズ.Height = n値;
1414                         i++;
1415                         //-----------------
1416                         #endregion
1417                         #region [ 4. 終了転送サイズ・幅 ]
1418                         //-----------------
1419                         n値 = 0;
1420                         if (!int.TryParse(strParams[i], out n値))
1421                         {
1422                                 Trace.TraceError("AVIPAN: {2}番目の引数(終了転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1423                                 return false;
1424                         }
1425                         avipan.sz終了サイズ.Width = n値;
1426                         i++;
1427                         //-----------------
1428                         #endregion
1429                         #region [ 5. 終了転送サイズ・高さ ]
1430                         //-----------------
1431                         n値 = 0;
1432                         if (!int.TryParse(strParams[i], out n値))
1433                         {
1434                                 Trace.TraceError("AVIPAN: {2}番目の引数(終了転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1435                                 return false;
1436                         }
1437                         avipan.sz終了サイズ.Height = n値;
1438                         i++;
1439                         //-----------------
1440                         #endregion
1441                         #region [ 6. 動画側開始位置・X ]
1442                         //-----------------
1443                         n値 = 0;
1444                         if (!int.TryParse(strParams[i], out n値))
1445                         {
1446                                 Trace.TraceError("AVIPAN: {2}番目の引数(動画側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1447                                 return false;
1448                         }
1449                         avipan.pt動画側開始位置.X = n値;
1450                         i++;
1451                         //-----------------
1452                         #endregion
1453                         #region [ 7. 動画側開始位置・Y ]
1454                         //-----------------
1455                         n値 = 0;
1456                         if (!int.TryParse(strParams[i], out n値))
1457                         {
1458                                 Trace.TraceError("AVIPAN: {2}番目の引数(動画側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1459                                 return false;
1460                         }
1461                         avipan.pt動画側開始位置.Y = n値;
1462                         i++;
1463                         //-----------------
1464                         #endregion
1465                         #region [ 8. 動画側終了位置・X ]
1466                         //-----------------
1467                         n値 = 0;
1468                         if (!int.TryParse(strParams[i], out n値))
1469                         {
1470                                 Trace.TraceError("AVIPAN: {2}番目の引数(動画側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1471                                 return false;
1472                         }
1473                         avipan.pt動画側終了位置.X = n値;
1474                         i++;
1475                         //-----------------
1476                         #endregion
1477                         #region [ 9. 動画側終了位置・Y ]
1478                         //-----------------
1479                         n値 = 0;
1480                         if (!int.TryParse(strParams[i], out n値))
1481                         {
1482                                 Trace.TraceError("AVIPAN: {2}番目の引数(動画側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1483                                 return false;
1484                         }
1485                         avipan.pt動画側終了位置.Y = n値;
1486                         i++;
1487                         //-----------------
1488                         #endregion
1489                         #region [ 10.表示側開始位置・X ]
1490                         //-----------------
1491                         n値 = 0;
1492                         if (!int.TryParse(strParams[i], out n値))
1493                         {
1494                                 Trace.TraceError("AVIPAN: {2}番目の引数(表示側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1495                                 return false;
1496                         }
1497                         avipan.pt表示側開始位置.X = n値;
1498                         i++;
1499                         //-----------------
1500                         #endregion
1501                         #region [ 11.表示側開始位置・Y ]
1502                         //-----------------
1503                         n値 = 0;
1504                         if (!int.TryParse(strParams[i], out n値))
1505                         {
1506                                 Trace.TraceError("AVIPAN: {2}番目の引数(表示側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1507                                 return false;
1508                         }
1509                         avipan.pt表示側開始位置.Y = n値;
1510                         i++;
1511                         //-----------------
1512                         #endregion
1513                         #region [ 12.表示側終了位置・X ]
1514                         //-----------------
1515                         n値 = 0;
1516                         if (!int.TryParse(strParams[i], out n値))
1517                         {
1518                                 Trace.TraceError("AVIPAN: {2}番目の引数(表示側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1519                                 return false;
1520                         }
1521                         avipan.pt表示側終了位置.X = n値;
1522                         i++;
1523                         //-----------------
1524                         #endregion
1525                         #region [ 13.表示側終了位置・Y ]
1526                         //-----------------
1527                         n値 = 0;
1528                         if (!int.TryParse(strParams[i], out n値))
1529                         {
1530                                 Trace.TraceError("AVIPAN: {2}番目の引数(表示側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1531                                 return false;
1532                         }
1533                         avipan.pt表示側終了位置.Y = n値;
1534                         i++;
1535                         //-----------------
1536                         #endregion
1537                         #region [ 14.移動時間 ]
1538                         //-----------------
1539                         n値 = 0;
1540                         if (!int.TryParse(strParams[i], out n値))
1541                         {
1542                                 Trace.TraceError("AVIPAN: {2}番目の引数(移動時間)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1543                                 return false;
1544                         }
1545
1546                         if (n値 < 0)
1547                                 n値 = 0;
1548
1549                         avipan.n移動時間ct = n値;
1550                         i++;
1551                         //-----------------
1552                         #endregion
1553
1554                         #region [ AVIPANリストに {zz, avipan} の組を登録する。]
1555                         //-----------------
1556                         if (this.listAVIPAN.ContainsKey(zz))  // 既にリスト中に存在しているなら削除。後のものが有効。
1557                                 this.listAVIPAN.Remove(zz);
1558
1559                         this.listAVIPAN.Add(zz, avipan);
1560                         //-----------------
1561                         #endregion
1562
1563                         return true;
1564                 }
1565                 private bool t入力_行解析_BGA(string strコマンド, string strパラメータ, string strコメント)
1566                 {
1567                         // (1) コマンドを処理。
1568
1569                         #region [ "BGA" で始まらないコマンドは無効。]
1570                         //-----------------
1571                         if (!strコマンド.StartsWith("BGA", StringComparison.OrdinalIgnoreCase))
1572                                 return false;
1573
1574                         strコマンド = strコマンド.Substring(3); // strコマンド から先頭の"BGA"文字を除去。
1575                                                                                                                                                         //-----------------
1576                         #endregion
1577
1578                         // (2) パラメータを処理。
1579
1580                         if (strコマンド.Length < 2)
1581                                 return false; // BGA番号 zz がないなら無効。
1582
1583                         #region [ BGA番号 zz を取得する。]
1584                         //-----------------
1585                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
1586                         if (zz < 0 || zz >= 36 * 36)
1587                         {
1588                                 Trace.TraceError("BGA番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
1589                                 return false;
1590                         }
1591                         //-----------------
1592                         #endregion
1593
1594                         var bga = new CBGA()
1595                         {
1596                                 n番号 = zz,
1597                         };
1598
1599                         // パラメータ引数(7個)を取得し、bga に登録していく。
1600
1601                         string[] strParams = strパラメータ.Split(new char[] { ' ', ',', '(', ')', '[', ']', 'x', '|' }, StringSplitOptions.RemoveEmptyEntries);
1602
1603                         #region [ パラメータ引数は全7個ないと無効。]
1604                         //-----------------
1605                         if (strParams.Length < 7)
1606                         {
1607                                 Trace.TraceError("BGA: 引数が足りません。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
1608                                 return false;
1609                         }
1610                         //-----------------
1611                         #endregion
1612
1613                         int i = 0;
1614                         int n値 = 0;
1615
1616                         #region [ 1.BMP番号 ]
1617                         //-----------------
1618                         if (string.IsNullOrEmpty(strParams[i]) || strParams[i].Length > 2)
1619                         {
1620                                 Trace.TraceError("BGA: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1621                                 return false;
1622                         }
1623                         bga.nBMP番号 = C変換.n36進数2桁の文字列を数値に変換して返す(strParams[i]);
1624                         if (bga.nBMP番号 < 1 || bga.nBMP番号 >= 36 * 36)
1625                         {
1626                                 Trace.TraceError("BGA: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1627                                 return false;
1628                         }
1629                         i++;
1630                         //-----------------
1631                         #endregion
1632                         #region [ 2.画像側位置1・X ]
1633                         //-----------------
1634                         n値 = 0;
1635                         if (!int.TryParse(strParams[i], out n値))
1636                         {
1637                                 Trace.TraceError("BGA: {2}番目の引数(画像側位置1・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1638                                 return false;
1639                         }
1640                         bga.pt画像側左上座標.X = n値;
1641                         i++;
1642                         //-----------------
1643                         #endregion
1644                         #region [ 3.画像側位置1・Y ]
1645                         //-----------------
1646                         n値 = 0;
1647                         if (!int.TryParse(strParams[i], out n値))
1648                         {
1649                                 Trace.TraceError("BGA: {2}番目の引数(画像側位置1・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1650                                 return false;
1651                         }
1652                         bga.pt画像側左上座標.Y = n値;
1653                         i++;
1654                         //-----------------
1655                         #endregion
1656                         #region [ 4.画像側位置2・X ]
1657                         //-----------------
1658                         n値 = 0;
1659                         if (!int.TryParse(strParams[i], out n値))
1660                         {
1661                                 Trace.TraceError("BGA: {2}番目の引数(画像側位置2・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1662                                 return false;
1663                         }
1664                         bga.pt画像側右下座標.X = n値;
1665                         i++;
1666                         //-----------------
1667                         #endregion
1668                         #region [ 5.画像側位置2・Y ]
1669                         //-----------------
1670                         n値 = 0;
1671                         if (!int.TryParse(strParams[i], out n値))
1672                         {
1673                                 Trace.TraceError("BGA: {2}番目の引数(画像側座標2・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1674                                 return false;
1675                         }
1676                         bga.pt画像側右下座標.Y = n値;
1677                         i++;
1678                         //-----------------
1679                         #endregion
1680                         #region [ 6.表示位置・X ]
1681                         //-----------------
1682                         n値 = 0;
1683                         if (!int.TryParse(strParams[i], out n値))
1684                         {
1685                                 Trace.TraceError("BGA: {2}番目の引数(表示位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1686                                 return false;
1687                         }
1688                         bga.pt表示座標.X = n値;
1689                         i++;
1690                         //-----------------
1691                         #endregion
1692                         #region [ 7.表示位置・Y ]
1693                         //-----------------
1694                         n値 = 0;
1695                         if (!int.TryParse(strParams[i], out n値))
1696                         {
1697                                 Trace.TraceError("BGA: {2}番目の引数(表示位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1698                                 return false;
1699                         }
1700                         bga.pt表示座標.Y = n値;
1701                         i++;
1702                         //-----------------
1703                         #endregion
1704
1705                         #region [ 画像側座標の正規化とクリッピング。]
1706                         //-----------------
1707                         if (bga.pt画像側左上座標.X > bga.pt画像側右下座標.X)
1708                         {
1709                                 n値 = bga.pt画像側左上座標.X;
1710                                 bga.pt画像側左上座標.X = bga.pt画像側右下座標.X;
1711                                 bga.pt画像側右下座標.X = n値;
1712                         }
1713                         if (bga.pt画像側左上座標.Y > bga.pt画像側右下座標.Y)
1714                         {
1715                                 n値 = bga.pt画像側左上座標.Y;
1716                                 bga.pt画像側左上座標.Y = bga.pt画像側右下座標.Y;
1717                                 bga.pt画像側右下座標.Y = n値;
1718                         }
1719                         //-----------------
1720                         #endregion
1721                         #region [ BGAリストに {zz, bga} の組を登録する。]
1722                         //-----------------
1723                         if (this.listBGA.ContainsKey(zz)) // 既にリスト中に存在しているなら削除。後のものが有効。
1724                                 this.listBGA.Remove(zz);
1725
1726                         this.listBGA.Add(zz, bga);
1727                         //-----------------
1728                         #endregion
1729
1730                         return true;
1731                 }
1732                 private bool t入力_行解析_BGAPAN(string strコマンド, string strパラメータ, string strコメント)
1733                 {
1734                         // (1) コマンドを処理。
1735
1736                         #region [ "BGAPAN" で始まらないコマンドは無効。]
1737                         //-----------------
1738                         if (!strコマンド.StartsWith("BGAPAN", StringComparison.OrdinalIgnoreCase))
1739                                 return false;
1740
1741                         strコマンド = strコマンド.Substring(6); // strコマンド から先頭の"BGAPAN"文字を除去。
1742                                                                                                                                                         //-----------------
1743                         #endregion
1744
1745                         // (2) パラメータを処理。
1746
1747                         if (strコマンド.Length < 2)
1748                                 return false; // BGAPAN番号 zz がないなら無効。
1749
1750                         #region [ BGAPAN番号 zz を取得する。]
1751                         //-----------------
1752                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
1753                         if (zz < 0 || zz >= 36 * 36)
1754                         {
1755                                 Trace.TraceError("BGAPAN番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
1756                                 return false;
1757                         }
1758                         //-----------------
1759                         #endregion
1760
1761                         var bgapan = new CBGAPAN()
1762                         {
1763                                 n番号 = zz,
1764                         };
1765
1766                         // パラメータ引数(14個)を取得し、bgapan に登録していく。
1767
1768                         string[] strParams = strパラメータ.Split(new char[] { ' ', ',', '(', ')', '[', ']', 'x', '|' }, StringSplitOptions.RemoveEmptyEntries);
1769
1770                         #region [ パラメータ引数は全14個ないと無効。]
1771                         //-----------------
1772                         if (strParams.Length < 14)
1773                         {
1774                                 Trace.TraceError("BGAPAN: 引数が足りません。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
1775                                 return false;
1776                         }
1777                         //-----------------
1778                         #endregion
1779
1780                         int i = 0;
1781                         int n値 = 0;
1782
1783                         #region [ 1. BMP番号 ]
1784                         //-----------------
1785                         if (string.IsNullOrEmpty(strParams[i]) || strParams[i].Length > 2)
1786                         {
1787                                 Trace.TraceError("BGAPAN: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1788                                 return false;
1789                         }
1790                         bgapan.nBMP番号 = C変換.n36進数2桁の文字列を数値に変換して返す(strParams[i]);
1791                         if (bgapan.nBMP番号 < 1 || bgapan.nBMP番号 >= 36 * 36)
1792                         {
1793                                 Trace.TraceError("BGAPAN: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1794                                 return false;
1795                         }
1796                         i++;
1797                         //-----------------
1798                         #endregion
1799                         #region [ 2. 開始転送サイズ・幅 ]
1800                         //-----------------
1801                         n値 = 0;
1802                         if (!int.TryParse(strParams[i], out n値))
1803                         {
1804                                 Trace.TraceError("BGAPAN: {2}番目の引数(開始転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1805                                 return false;
1806                         }
1807                         bgapan.sz開始サイズ.Width = n値;
1808                         i++;
1809                         //-----------------
1810                         #endregion
1811                         #region [ 3. 開始転送サイズ・高さ ]
1812                         //-----------------
1813                         n値 = 0;
1814                         if (!int.TryParse(strParams[i], out n値))
1815                         {
1816                                 Trace.TraceError("BGAPAN: {2}番目の引数(開始転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1817                                 return false;
1818                         }
1819                         bgapan.sz開始サイズ.Height = n値;
1820                         i++;
1821                         //-----------------
1822                         #endregion
1823                         #region [ 4. 終了転送サイズ・幅 ]
1824                         //-----------------
1825                         n値 = 0;
1826                         if (!int.TryParse(strParams[i], out n値))
1827                         {
1828                                 Trace.TraceError("BGAPAN: {2}番目の引数(終了転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1829                                 return false;
1830                         }
1831                         bgapan.sz終了サイズ.Width = n値;
1832                         i++;
1833                         //-----------------
1834                         #endregion
1835                         #region [ 5. 終了転送サイズ・高さ ]
1836                         //-----------------
1837                         n値 = 0;
1838                         if (!int.TryParse(strParams[i], out n値))
1839                         {
1840                                 Trace.TraceError("BGAPAN: {2}番目の引数(終了転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1841                                 return false;
1842                         }
1843                         bgapan.sz終了サイズ.Height = n値;
1844                         i++;
1845                         //-----------------
1846                         #endregion
1847                         #region [ 6. 画像側開始位置・X ]
1848                         //-----------------
1849                         n値 = 0;
1850                         if (!int.TryParse(strParams[i], out n値))
1851                         {
1852                                 Trace.TraceError("BGAPAN: {2}番目の引数(画像側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1853                                 return false;
1854                         }
1855                         bgapan.pt画像側開始位置.X = n値;
1856                         i++;
1857                         //-----------------
1858                         #endregion
1859                         #region [ 7. 画像側開始位置・Y ]
1860                         //-----------------
1861                         n値 = 0;
1862                         if (!int.TryParse(strParams[i], out n値))
1863                         {
1864                                 Trace.TraceError("BGAPAN: {2}番目の引数(画像側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1865                                 return false;
1866                         }
1867                         bgapan.pt画像側開始位置.Y = n値;
1868                         i++;
1869                         //-----------------
1870                         #endregion
1871                         #region [ 8. 画像側終了位置・X ]
1872                         //-----------------
1873                         n値 = 0;
1874                         if (!int.TryParse(strParams[i], out n値))
1875                         {
1876                                 Trace.TraceError("BGAPAN: {2}番目の引数(画像側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1877                                 return false;
1878                         }
1879                         bgapan.pt画像側終了位置.X = n値;
1880                         i++;
1881                         //-----------------
1882                         #endregion
1883                         #region [ 9. 画像側終了位置・Y ]
1884                         //-----------------
1885                         n値 = 0;
1886                         if (!int.TryParse(strParams[i], out n値))
1887                         {
1888                                 Trace.TraceError("BGAPAN: {2}番目の引数(画像側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1889                                 return false;
1890                         }
1891                         bgapan.pt画像側終了位置.Y = n値;
1892                         i++;
1893                         //-----------------
1894                         #endregion
1895                         #region [ 10.表示側開始位置・X ]
1896                         //-----------------
1897                         n値 = 0;
1898                         if (!int.TryParse(strParams[i], out n値))
1899                         {
1900                                 Trace.TraceError("BGAPAN: {2}番目の引数(表示側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1901                                 return false;
1902                         }
1903                         bgapan.pt表示側開始位置.X = n値;
1904                         i++;
1905                         //-----------------
1906                         #endregion
1907                         #region [ 11.表示側開始位置・Y ]
1908                         //-----------------
1909                         n値 = 0;
1910                         if (!int.TryParse(strParams[i], out n値))
1911                         {
1912                                 Trace.TraceError("BGAPAN: {2}番目の引数(表示側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1913                                 return false;
1914                         }
1915                         bgapan.pt表示側開始位置.Y = n値;
1916                         i++;
1917                         //-----------------
1918                         #endregion
1919                         #region [ 12.表示側終了位置・X ]
1920                         //-----------------
1921                         n値 = 0;
1922                         if (!int.TryParse(strParams[i], out n値))
1923                         {
1924                                 Trace.TraceError("BGAPAN: {2}番目の引数(表示側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1925                                 return false;
1926                         }
1927                         bgapan.pt表示側終了位置.X = n値;
1928                         i++;
1929                         //-----------------
1930                         #endregion
1931                         #region [ 13.表示側終了位置・Y ]
1932                         //-----------------
1933                         n値 = 0;
1934                         if (!int.TryParse(strParams[i], out n値))
1935                         {
1936                                 Trace.TraceError("BGAPAN: {2}番目の引数(表示側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1937                                 return false;
1938                         }
1939                         bgapan.pt表示側終了位置.Y = n値;
1940                         i++;
1941                         //-----------------
1942                         #endregion
1943                         #region [ 14.移動時間 ]
1944                         //-----------------
1945                         n値 = 0;
1946                         if (!int.TryParse(strParams[i], out n値))
1947                         {
1948                                 Trace.TraceError("BGAPAN: {2}番目の引数(移動時間)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1);
1949                                 return false;
1950                         }
1951
1952                         if (n値 < 0)
1953                                 n値 = 0;
1954
1955                         bgapan.n移動時間ct = n値;
1956                         i++;
1957                         //-----------------
1958                         #endregion
1959
1960                         #region [ BGAPANリストに {zz, bgapan} の組を登録する。]
1961                         //-----------------
1962                         if (this.listBGAPAN.ContainsKey(zz))  // 既にリスト中に存在しているなら削除。後のものが有効。
1963                                 this.listBGAPAN.Remove(zz);
1964
1965                         this.listBGAPAN.Add(zz, bgapan);
1966                         //-----------------
1967                         #endregion
1968
1969                         return true;
1970                 }
1971                 private bool t入力_行解析_BMP(string strコマンド, string strパラメータ, string strコメント)
1972                 {
1973                         // (1) コマンドを処理。
1974
1975                         #region [ "BMP" で始まらないコマンドは無効。]
1976                         //-----------------
1977                         if (!strコマンド.StartsWith("BMP", StringComparison.OrdinalIgnoreCase))
1978                                 return false;
1979
1980                         strコマンド = strコマンド.Substring(3); // strコマンド から先頭の"BMP"文字を除去。
1981                                                                                                                                                         //-----------------
1982                         #endregion
1983
1984                         // (2) パラメータを処理。
1985
1986                         int zz = 0;
1987
1988                         #region [ BMP番号 zz を取得する。]
1989                         //-----------------
1990                         if (strコマンド.Length < 2)
1991                         {
1992                                 #region [ (A) "#BMP:" の場合 → zz = 00 ]
1993                                 //-----------------
1994                                 zz = 0;
1995                                 //-----------------
1996                                 #endregion
1997                         }
1998                         else
1999                         {
2000                                 #region [ (B) "#BMPzz:" の場合 → zz = 00 ~ ZZ ]
2001                                 //-----------------
2002                                 zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
2003                                 if (zz < 0 || zz >= 36 * 36)
2004                                 {
2005                                         Trace.TraceError("BMP番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2006                                         return false;
2007                                 }
2008                                 //-----------------
2009                                 #endregion
2010                         }
2011                         //-----------------
2012                         #endregion
2013
2014
2015                         var bmp = new CBMP()
2016                         {
2017                                 n番号 = zz,
2018                                 strファイル名 = strパラメータ,
2019                                 strコメント文 = strコメント,
2020                         };
2021
2022                         #region [ BMPリストに {zz, bmp} の組を登録。]
2023                         //-----------------
2024                         if (this.listBMP.ContainsKey(zz)) // 既にリスト中に存在しているなら削除。後のものが有効。
2025                                 this.listBMP.Remove(zz);
2026
2027                         this.listBMP.Add(zz, bmp);
2028                         //-----------------
2029                         #endregion
2030
2031                         return true;
2032                 }
2033                 private bool t入力_行解析_BMPTEX(string strコマンド, string strパラメータ, string strコメント)
2034                 {
2035                         // (1) コマンドを処理。
2036
2037                         #region [ "BMPTEX" で始まらないコマンドは無効。]
2038                         //-----------------
2039                         if (!strコマンド.StartsWith("BMPTEX", StringComparison.OrdinalIgnoreCase))
2040                                 return false;
2041
2042                         strコマンド = strコマンド.Substring(6); // strコマンド から先頭の"BMPTEX"文字を除去。
2043                                                                                                                                                         //-----------------
2044                         #endregion
2045
2046                         // (2) パラメータを処理。
2047
2048                         if (strコマンド.Length < 2)
2049                                 return false; // BMPTEX番号 zz がないなら無効。
2050
2051                         #region [ BMPTEX番号 zz を取得する。]
2052                         //-----------------
2053                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
2054                         if (zz < 0 || zz >= 36 * 36)
2055                         {
2056                                 Trace.TraceError("BMPTEX番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}]", this.strファイル名の絶対パス, this.n現在の行数);
2057                                 return false;
2058                         }
2059                         //-----------------
2060                         #endregion
2061
2062                         var bmptex = new CBMPTEX()
2063                         {
2064                                 n番号 = zz,
2065                                 strファイル名 = strパラメータ,
2066                                 strコメント文 = strコメント,
2067                         };
2068
2069                         #region [ BMPTEXリストに {zz, bmptex} の組を登録する。]
2070                         //-----------------
2071                         if (this.listBMPTEX.ContainsKey(zz))  // 既にリスト中に存在しているなら削除。後のものが有効。
2072                                 this.listBMPTEX.Remove(zz);
2073
2074                         this.listBMPTEX.Add(zz, bmptex);
2075                         //-----------------
2076                         #endregion
2077
2078                         return true;
2079                 }
2080                 private bool t入力_行解析_BPM_BPMzz(string strコマンド, string strパラメータ, string strコメント)
2081                 {
2082                         // (1) コマンドを処理。
2083
2084                         #region [ "BPM" で始まらないコマンドは無効。]
2085                         //-----------------
2086                         if (!strコマンド.StartsWith("BPM", StringComparison.OrdinalIgnoreCase))
2087                                 return false;
2088
2089                         strコマンド = strコマンド.Substring(3); // strコマンド から先頭の"BPM"文字を除去。
2090                                                                                                                                                         //-----------------
2091                         #endregion
2092
2093                         // (2) パラメータを処理。
2094
2095                         int zz = 0;
2096
2097                         #region [ BPM番号 zz を取得する。]
2098                         //-----------------
2099                         if (strコマンド.Length < 2)
2100                         {
2101                                 #region [ (A) "#BPM:" の場合 → zz = 00 ]
2102                                 //-----------------
2103                                 zz = 0;
2104                                 //-----------------
2105                                 #endregion
2106                         }
2107                         else
2108                         {
2109                                 #region [ (B) "#BPMzz:" の場合 → zz = 00 ~ ZZ ]
2110                                 //-----------------
2111                                 zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
2112                                 if (zz < 0 || zz >= 36 * 36)
2113                                 {
2114                                         Trace.TraceError("BPM番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2115                                         return false;
2116                                 }
2117                                 //-----------------
2118                                 #endregion
2119                         }
2120                         //-----------------
2121                         #endregion
2122
2123                         double dbBPM = 0.0;
2124
2125                         #region [ BPM値を取得する。]
2126                         //-----------------
2127                         //if( !double.TryParse( strパラメータ, out result ) )
2128                         if (!TryParse(strパラメータ, out dbBPM))     // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point
2129                                 return false;
2130
2131                         if (dbBPM <= 0.0)
2132                                 return false;
2133                         //-----------------
2134                         #endregion
2135
2136                         if (zz == 0)      // "#BPM00:" と "#BPM:" は等価。
2137                                 this.BPM = dbBPM; // この曲の代表 BPM に格納する。
2138
2139                         #region [ BPMリストに {内部番号, zz, dbBPM} の組を登録。]
2140                         //-----------------
2141                         this.listBPM.Add(
2142                                 this.n内部番号BPM1to,
2143                                 new CBPM()
2144                                 {
2145                                         n内部番号 = this.n内部番号BPM1to,
2146                                         n表記上の番号 = zz,
2147                                         dbBPM値 = dbBPM,
2148                                 });
2149                         //-----------------
2150                         #endregion
2151
2152                         #region [ BPM番号が zz であるBPM未設定のBPMチップがあれば、そのサイズを変更する。無限管理に対応。]
2153                         //-----------------
2154                         if (this.n無限管理BPM[zz] == -zz) // 初期状態では n無限管理BPM[zz] = -zz である。この場合、#BPMzz がまだ出現していないことを意味する。
2155                         {
2156                                 foreach (CChip chip in listChip)  // これまでに出てきたチップのうち、該当する(BPM値が未設定の)BPMチップの値を変更する(仕組み上、必ず後方参照となる)。
2157                                 {
2158                                         chip.AdjustInfiniteManageIntInternalIndex(chip.bBPMチップである, zz, this.n内部番号BPM1to);
2159                                 }
2160                         }
2161                         this.n無限管理BPM[zz] = this.n内部番号BPM1to;     // 次にこの BPM番号 zz を使うBPMチップが現れたら、このBPM値が格納されることになる。
2162                         this.n内部番号BPM1to++;   // 内部番号は単純増加連番。
2163                                                                                                                 //-----------------
2164                         #endregion
2165
2166                         return true;
2167                 }
2168                 private bool t入力_行解析_RESULTIMAGE(string strコマンド, string strパラメータ, string strコメント)
2169                 {
2170                         // (1) コマンドを処理。
2171
2172                         #region [ "RESULTIMAGE" で始まらないコマンドは無効。]
2173                         //-----------------
2174                         if (!strコマンド.StartsWith("RESULTIMAGE", StringComparison.OrdinalIgnoreCase))
2175                                 return false;
2176
2177                         strコマンド = strコマンド.Substring(11);  // strコマンド から先頭の"RESULTIMAGE"文字を除去。
2178                                                                                                                                                                 //-----------------
2179                         #endregion
2180
2181                         // (2) パラメータを処理。
2182                         //     コマンドには "#RESULTIMAGE:" と "#RESULTIMAGE_SS~E" の2種類があり、パラメータの処理はそれぞれ異なる。
2183
2184                         if (strコマンド.Length < 2)
2185                         {
2186                                 #region [ (A) ランク指定がない場合("#RESULTIMAGE:") → 優先順位が設定されていないすべてのランクで同じパラメータを使用する。]
2187                                 //-----------------
2188                                 for (int i = 0; i < 7; i++)
2189                                 {
2190                                         if (this.nRESULTIMAGE用優先順位[i] == 0)
2191                                                 this.RESULTIMAGE[i] = strパラメータ.Trim();
2192                                 }
2193                                 //-----------------
2194                                 #endregion
2195                         }
2196                         else
2197                         {
2198                                 #region [ (B) ランク指定がある場合("#RESULTIMAGE_SS~E:") → 優先順位に従ってパラメータを記録する。]
2199                                 //-----------------
2200                                 switch (strコマンド.ToUpper())
2201                                 {
2202                                         case "_SS":
2203                                                 this.t入力_行解析_RESULTIMAGE_ファイルを設定する(0, strパラメータ);
2204                                                 break;
2205
2206                                         case "_S":
2207                                                 this.t入力_行解析_RESULTIMAGE_ファイルを設定する(1, strパラメータ);
2208                                                 break;
2209
2210                                         case "_A":
2211                                                 this.t入力_行解析_RESULTIMAGE_ファイルを設定する(2, strパラメータ);
2212                                                 break;
2213
2214                                         case "_B":
2215                                                 this.t入力_行解析_RESULTIMAGE_ファイルを設定する(3, strパラメータ);
2216                                                 break;
2217
2218                                         case "_C":
2219                                                 this.t入力_行解析_RESULTIMAGE_ファイルを設定する(4, strパラメータ);
2220                                                 break;
2221
2222                                         case "_D":
2223                                                 this.t入力_行解析_RESULTIMAGE_ファイルを設定する(5, strパラメータ);
2224                                                 break;
2225
2226                                         case "_E":
2227                                                 this.t入力_行解析_RESULTIMAGE_ファイルを設定する(6, strパラメータ);
2228                                                 break;
2229                                 }
2230                                 //-----------------
2231                                 #endregion
2232                         }
2233
2234                         return true;
2235                 }
2236                 private void t入力_行解析_RESULTIMAGE_ファイルを設定する(int nランク0to6, string strファイル名)
2237                 {
2238                         if (nランク0to6 < 0 || nランク0to6 > 6) // 値域チェック。
2239                                 return;
2240
2241                         // 指定されたランクから上位のすべてのランクについて、ファイル名を更新する。
2242
2243                         for (int i = nランク0to6; i >= 0; i--)
2244                         {
2245                                 int n優先順位 = 7 - nランク0to6;
2246
2247                                 // 現状より優先順位の低い RESULTIMAGE[] に限り、ファイル名を更新できる。
2248                                 //(例:#RESULTMOVIE_D が #RESULTIMAGE_A より後に出現しても、#RESULTIMAGE_A で指定されたファイル名を上書きすることはできない。しかしその逆は可能。)
2249
2250                                 if (this.nRESULTIMAGE用優先順位[i] < n優先順位)
2251                                 {
2252                                         this.nRESULTIMAGE用優先順位[i] = n優先順位;
2253                                         this.RESULTIMAGE[i] = strファイル名;
2254                                 }
2255                         }
2256                 }
2257                 private bool t入力_行解析_RESULTMOVIE(string strコマンド, string strパラメータ, string strコメント)
2258                 {
2259                         // (1) コマンドを処理。
2260
2261                         #region [ "RESULTMOVIE" で始まらないコマンドは無効。]
2262                         //-----------------
2263                         if (!strコマンド.StartsWith("RESULTMOVIE", StringComparison.OrdinalIgnoreCase))
2264                                 return false;
2265
2266                         strコマンド = strコマンド.Substring(11);  // strコマンド から先頭の"RESULTMOVIE"文字を除去。
2267                                                                                                                                                                 //-----------------
2268                         #endregion
2269
2270                         // (2) パラメータを処理。
2271                         //     コマンドには "#RESULTMOVIE:" と "#RESULTMOVIE_SS~E" の2種類があり、パラメータの処理はそれぞれ異なる。
2272
2273                         if (strコマンド.Length < 2)
2274                         {
2275                                 #region [ (A) ランク指定がない場合("#RESULTMOVIE:") → 優先順位が設定されていないすべてのランクで同じパラメータを使用する。]
2276                                 //-----------------
2277                                 for (int i = 0; i < 7; i++)
2278                                 {
2279                                         if (this.nRESULTMOVIE用優先順位[i] == 0)
2280                                                 this.RESULTMOVIE[i] = strパラメータ.Trim();
2281                                 }
2282                                 //-----------------
2283                                 #endregion
2284                         }
2285                         else
2286                         {
2287                                 #region [ (B) ランク指定がある場合("#RESULTMOVIE_SS~E:") → 優先順位に従ってパラメータを記録する。]
2288                                 //-----------------
2289                                 switch (strコマンド.ToUpper())
2290                                 {
2291                                         case "_SS":
2292                                                 this.t入力_行解析_RESULTMOVIE_ファイルを設定する(0, strパラメータ);
2293                                                 break;
2294
2295                                         case "_S":
2296                                                 this.t入力_行解析_RESULTMOVIE_ファイルを設定する(1, strパラメータ);
2297                                                 break;
2298
2299                                         case "_A":
2300                                                 this.t入力_行解析_RESULTMOVIE_ファイルを設定する(2, strパラメータ);
2301                                                 break;
2302
2303                                         case "_B":
2304                                                 this.t入力_行解析_RESULTMOVIE_ファイルを設定する(3, strパラメータ);
2305                                                 break;
2306
2307                                         case "_C":
2308                                                 this.t入力_行解析_RESULTMOVIE_ファイルを設定する(4, strパラメータ);
2309                                                 break;
2310
2311                                         case "_D":
2312                                                 this.t入力_行解析_RESULTMOVIE_ファイルを設定する(5, strパラメータ);
2313                                                 break;
2314
2315                                         case "_E":
2316                                                 this.t入力_行解析_RESULTMOVIE_ファイルを設定する(6, strパラメータ);
2317                                                 break;
2318                                 }
2319                                 //-----------------
2320                                 #endregion
2321                         }
2322
2323                         return true;
2324                 }
2325                 private void t入力_行解析_RESULTMOVIE_ファイルを設定する(int nランク0to6, string strファイル名)
2326                 {
2327                         if (nランク0to6 < 0 || nランク0to6 > 6) // 値域チェック。
2328                                 return;
2329
2330                         // 指定されたランクから上位のすべてのランクについて、ファイル名を更新する。
2331
2332                         for (int i = nランク0to6; i >= 0; i--)
2333                         {
2334                                 int n優先順位 = 7 - nランク0to6;
2335
2336                                 // 現状より優先順位の低い RESULTMOVIE[] に限り、ファイル名を更新できる。
2337                                 //(例:#RESULTMOVIE_D が #RESULTMOVIE_A より後に出現しても、#RESULTMOVIE_A で指定されたファイル名を上書きすることはできない。しかしその逆は可能。)
2338
2339                                 if (this.nRESULTMOVIE用優先順位[i] < n優先順位)
2340                                 {
2341                                         this.nRESULTMOVIE用優先順位[i] = n優先順位;
2342                                         this.RESULTMOVIE[i] = strファイル名;
2343                                 }
2344                         }
2345                 }
2346                 private bool t入力_行解析_RESULTSOUND(string strコマンド, string strパラメータ, string strコメント)
2347                 {
2348                         // (1) コマンドを処理。
2349
2350                         #region [ "RESULTSOUND" で始まらないコマンドは無効。]
2351                         //-----------------
2352                         if (!strコマンド.StartsWith("RESULTSOUND", StringComparison.OrdinalIgnoreCase))
2353                                 return false;
2354
2355                         strコマンド = strコマンド.Substring(11);  // strコマンド から先頭の"RESULTSOUND"文字を除去。
2356                                                                                                                                                                 //-----------------
2357                         #endregion
2358
2359                         // (2) パラメータを処理。
2360                         //     コマンドには "#RESULTSOUND:" と "#RESULTSOUND_SS~E" の2種類があり、パラメータの処理はそれぞれ異なる。
2361
2362                         if (strコマンド.Length < 2)
2363                         {
2364                                 #region [ (A) ランク指定がない場合("#RESULTSOUND:") → 優先順位が設定されていないすべてのランクで同じパラメータを使用する。]
2365                                 //-----------------
2366                                 for (int i = 0; i < 7; i++)
2367                                 {
2368                                         if (this.nRESULTSOUND用優先順位[i] == 0)
2369                                                 this.RESULTSOUND[i] = strパラメータ.Trim();
2370                                 }
2371                                 //-----------------
2372                                 #endregion
2373                         }
2374                         else
2375                         {
2376                                 #region [ (B) ランク指定がある場合("#RESULTSOUND_SS~E:") → 優先順位に従ってパラメータを記録する。]
2377                                 //-----------------
2378                                 switch (strコマンド.ToUpper())
2379                                 {
2380                                         case "_SS":
2381                                                 this.t入力_行解析_RESULTSOUND_ファイルを設定する(0, strパラメータ);
2382                                                 break;
2383
2384                                         case "_S":
2385                                                 this.t入力_行解析_RESULTSOUND_ファイルを設定する(1, strパラメータ);
2386                                                 break;
2387
2388                                         case "_A":
2389                                                 this.t入力_行解析_RESULTSOUND_ファイルを設定する(2, strパラメータ);
2390                                                 break;
2391
2392                                         case "_B":
2393                                                 this.t入力_行解析_RESULTSOUND_ファイルを設定する(3, strパラメータ);
2394                                                 break;
2395
2396                                         case "_C":
2397                                                 this.t入力_行解析_RESULTSOUND_ファイルを設定する(4, strパラメータ);
2398                                                 break;
2399
2400                                         case "_D":
2401                                                 this.t入力_行解析_RESULTSOUND_ファイルを設定する(5, strパラメータ);
2402                                                 break;
2403
2404                                         case "_E":
2405                                                 this.t入力_行解析_RESULTSOUND_ファイルを設定する(6, strパラメータ);
2406                                                 break;
2407                                 }
2408                                 //-----------------
2409                                 #endregion
2410                         }
2411
2412                         return true;
2413                 }
2414                 private void t入力_行解析_RESULTSOUND_ファイルを設定する(int nランク0to6, string strファイル名)
2415                 {
2416                         if (nランク0to6 < 0 || nランク0to6 > 6) // 値域チェック。
2417                                 return;
2418
2419                         // 指定されたランクから上位のすべてのランクについて、ファイル名を更新する。
2420
2421                         for (int i = nランク0to6; i >= 0; i--)
2422                         {
2423                                 int n優先順位 = 7 - nランク0to6;
2424
2425                                 // 現状より優先順位の低い RESULTSOUND[] に限り、ファイル名を更新できる。
2426                                 //(例:#RESULTSOUND_D が #RESULTSOUND_A より後に出現しても、#RESULTSOUND_A で指定されたファイル名を上書きすることはできない。しかしその逆は可能。)
2427
2428                                 if (this.nRESULTSOUND用優先順位[i] < n優先順位)
2429                                 {
2430                                         this.nRESULTSOUND用優先順位[i] = n優先順位;
2431                                         this.RESULTSOUND[i] = strファイル名;
2432                                 }
2433                         }
2434                 }
2435                 private bool t入力_行解析_SIZE(string strコマンド, string strパラメータ, string strコメント)
2436                 {
2437                         // (1) コマンドを処理。
2438
2439                         #region [ "SIZE" で始まらないコマンドや、その後ろに2文字(番号)が付随してないコマンドは無効。]
2440                         //-----------------
2441                         if (!strコマンド.StartsWith("SIZE", StringComparison.OrdinalIgnoreCase))
2442                                 return false;
2443
2444                         strコマンド = strコマンド.Substring(4); // strコマンド から先頭の"SIZE"文字を除去。
2445
2446                         if (strコマンド.Length < 2) // サイズ番号の指定がない場合は無効。
2447                                 return false;
2448                         //-----------------
2449                         #endregion
2450
2451                         #region [ nWAV番号(36進数2桁)を取得。]
2452                         //-----------------
2453                         int nWAV番号 = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
2454
2455                         if (nWAV番号 < 0 || nWAV番号 >= 36 * 36)
2456                         {
2457                                 Trace.TraceError("SIZEのWAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2458                                 return false;
2459                         }
2460                         //-----------------
2461                         #endregion
2462
2463
2464                         // (2) パラメータを処理。
2465
2466                         #region [ nサイズ値 を取得する。値は 0~100 に収める。]
2467                         //-----------------
2468                         int nサイズ値;
2469
2470                         if (!int.TryParse(strパラメータ, out nサイズ値))
2471                                 return true;  // int変換に失敗しても、この行自体の処理は終えたのでtrueを返す。
2472
2473                         nサイズ値 = Math.Min(Math.Max(nサイズ値, 0), 100);  // 0未満は0、100超えは100に強制変換。
2474                                                                                                                                                                                                         //-----------------
2475                         #endregion
2476
2477                         #region [ nWAV番号で示されるサイズ未設定のWAVチップがあれば、そのサイズを変更する。無限管理に対応。]
2478                         //-----------------
2479                         if (this.n無限管理SIZE[nWAV番号] == -nWAV番号)  // 初期状態では n無限管理SIZE[xx] = -xx である。この場合、#SIZExx がまだ出現していないことを意味する。
2480                         {
2481                                 foreach (CWAV wav in this.listWAV.Values)   // これまでに出てきたWAVチップのうち、該当する(サイズが未設定の)チップのサイズを変更する(仕組み上、必ず後方参照となる)。
2482                                 {
2483                                         if (wav.nチップサイズ == -nWAV番号)   // #SIZExx 行より前の行に出現した #WAVxx では、チップサイズは -xx に初期化されている。
2484                                                 wav.nチップサイズ = nサイズ値;
2485                                 }
2486                         }
2487                         this.n無限管理SIZE[nWAV番号] = nサイズ値;     // 次にこの nWAV番号を使うWAVチップが現れたら、負数の代わりに、このサイズ値が格納されることになる。
2488                                                                                                                                                                         //-----------------
2489                         #endregion
2490
2491                         return true;
2492                 }
2493                 private bool t入力_行解析_WAV(string strコマンド, string strパラメータ, string strコメント)
2494                 {
2495                         // (1) コマンドを処理。
2496
2497                         #region [ "WAV" で始まらないコマンドは無効。]
2498                         //-----------------
2499                         if (!strコマンド.StartsWith("WAV", StringComparison.OrdinalIgnoreCase))
2500                                 return false;
2501
2502                         strコマンド = strコマンド.Substring(3); // strコマンド から先頭の"WAV"文字を除去。
2503                                                                                                                                                         //-----------------
2504                         #endregion
2505
2506                         // (2) パラメータを処理。
2507
2508                         if (strコマンド.Length < 2)
2509                                 return false; // WAV番号 zz がないなら無効。
2510
2511                         #region [ WAV番号 zz を取得する。]
2512                         //-----------------
2513                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
2514                         if (zz < 0 || zz >= 36 * 36)
2515                         {
2516                                 Trace.TraceError("WAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2517                                 return false;
2518                         }
2519                         //-----------------
2520                         #endregion
2521
2522                         var wav = new CWAV()
2523                         {
2524                                 n内部番号 = this.n内部番号WAV1to,
2525                                 n表記上の番号 = zz,
2526                                 nチップサイズ = this.n無限管理SIZE[zz],
2527                                 n位置 = this.n無限管理PAN[zz],
2528                                 n音量 = this.n無限管理VOL[zz],
2529                                 strファイル名 = strパラメータ,
2530                                 strコメント文 = strコメント,
2531                         };
2532
2533                         #region [ WAVリストに {内部番号, wav} の組を登録。]
2534                         //-----------------
2535                         this.listWAV.Add(this.n内部番号WAV1to, wav);
2536                         //-----------------
2537                         #endregion
2538
2539                         #region [ WAV番号が zz である内部番号未設定のWAVチップがあれば、その内部番号を変更する。無限管理対応。]
2540                         //-----------------
2541                         if (this.n無限管理WAV[zz] == -zz) // 初期状態では n無限管理WAV[zz] = -zz である。この場合、#WAVzz がまだ出現していないことを意味する。
2542                         {
2543                                 foreach (CChip chip in listChip)  // これまでに出てきたチップのうち、該当する(内部番号が未設定の)WAVチップの値を変更する(仕組み上、必ず後方参照となる)。
2544                                 {
2545                                         chip.AdjustInfiniteManageIntInternalIndex(chip.bWAVを使うチャンネルである, zz, n内部番号WAV1to);
2546                                 }
2547                         }
2548                         this.n無限管理WAV[zz] = this.n内部番号WAV1to;     // 次にこの WAV番号 zz を使うWAVチップが現れたら、この内部番号が格納されることになる。
2549                         this.n内部番号WAV1to++;   // 内部番号は単純増加連番。
2550                                                                                                                 //-----------------
2551                         #endregion
2552
2553                         return true;
2554                 }
2555                 private bool t入力_行解析_WAVPAN_PAN(string strコマンド, string strパラメータ, string strコメント)
2556                 {
2557                         // (1) コマンドを処理。
2558
2559                         #region [ "WAVPAN" or "PAN" で始まらないコマンドは無効。]
2560                         //-----------------
2561                         if (strコマンド.StartsWith("WAVPAN", StringComparison.OrdinalIgnoreCase))
2562                                 strコマンド = strコマンド.Substring(6);   // strコマンド から先頭の"WAVPAN"文字を除去。
2563
2564                         else if (strコマンド.StartsWith("PAN", StringComparison.OrdinalIgnoreCase))
2565                                 strコマンド = strコマンド.Substring(3);   // strコマンド から先頭の"PAN"文字を除去。
2566
2567                         else
2568                                 return false;
2569                         //-----------------
2570                         #endregion
2571
2572                         // (2) パラメータを処理。
2573
2574                         if (strコマンド.Length < 2)
2575                                 return false; // WAV番号 zz がないなら無効。
2576
2577                         #region [ WAV番号 zz を取得する。]
2578                         //-----------------
2579                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
2580                         if (zz < 0 || zz >= 36 * 36)
2581                         {
2582                                 Trace.TraceError("WAVPAN(PAN)のWAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2583                                 return false;
2584                         }
2585                         //-----------------
2586                         #endregion
2587
2588                         #region [ WAV番号 zz を持つWAVチップの位置を変更する。無限定義対応。]
2589                         //-----------------
2590                         int n位置;
2591                         if (int.TryParse(strパラメータ, out n位置))
2592                         {
2593                                 n位置 = Math.Min(Math.Max(n位置, -100), 100); // -100~+100 に丸める
2594
2595                                 if (this.n無限管理PAN[zz] == (-10000 - zz)) // 初期状態では n無限管理PAN[zz] = -10000 - zz である。この場合、#WAVPANzz, #PANzz がまだ出現していないことを意味する。
2596                                 {
2597                                         foreach (CWAV wav in this.listWAV.Values) // これまでに出てきたチップのうち、該当する(位置が未設定の)WAVチップの値を変更する(仕組み上、必ず後方参照となる)。
2598                                         {
2599                                                 if (wav.n位置 == (-10000 - zz)) // #WAVPANzz, #PANzz 行より前の行に出現した #WAVzz では、位置は -10000-zz に初期化されている。
2600                                                         wav.n位置 = n位置;
2601                                         }
2602                                 }
2603                                 this.n無限管理PAN[zz] = n位置;      // 次にこの WAV番号 zz を使うWAVチップが現れたら、この位置が格納されることになる。
2604                         }
2605                         //-----------------
2606                         #endregion
2607
2608                         return true;
2609                 }
2610                 private bool t入力_行解析_WAVVOL_VOLUME(string strコマンド, string strパラメータ, string strコメント)
2611                 {
2612                         // (1) コマンドを処理。
2613
2614                         #region [ "WAVCOL" or "VOLUME" で始まらないコマンドは無効。]
2615                         //-----------------
2616                         if (strコマンド.StartsWith("WAVVOL", StringComparison.OrdinalIgnoreCase))
2617                                 strコマンド = strコマンド.Substring(6);   // strコマンド から先頭の"WAVVOL"文字を除去。
2618
2619                         else if (strコマンド.StartsWith("VOLUME", StringComparison.OrdinalIgnoreCase))
2620                                 strコマンド = strコマンド.Substring(6);   // strコマンド から先頭の"VOLUME"文字を除去。
2621
2622                         else
2623                                 return false;
2624                         //-----------------
2625                         #endregion
2626
2627                         // (2) パラメータを処理。
2628
2629                         if (strコマンド.Length < 2)
2630                                 return false; // WAV番号 zz がないなら無効。
2631
2632                         #region [ WAV番号 zz を取得する。]
2633                         //-----------------
2634                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す(strコマンド.Substring(0, 2));
2635                         if (zz < 0 || zz >= 36 * 36)
2636                         {
2637                                 Trace.TraceError("WAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2638                                 return false;
2639                         }
2640                         //-----------------
2641                         #endregion
2642
2643                         #region [ WAV番号 zz を持つWAVチップの音量を変更する。無限定義対応。]
2644                         //-----------------
2645                         int n音量;
2646                         if (int.TryParse(strパラメータ, out n音量))
2647                         {
2648                                 n音量 = Math.Min(Math.Max(n音量, 0), 100);  // 0~100に丸める。
2649
2650                                 if (this.n無限管理VOL[zz] == -zz) // 初期状態では n無限管理VOL[zz] = - zz である。この場合、#WAVVOLzz, #VOLUMEzz がまだ出現していないことを意味する。
2651                                 {
2652                                         foreach (CWAV wav in this.listWAV.Values) // これまでに出てきたチップのうち、該当する(音量が未設定の)WAVチップの値を変更する(仕組み上、必ず後方参照となる)。
2653                                         {
2654                                                 if (wav.n音量 == -zz) // #WAVVOLzz, #VOLUMEzz 行より前の行に出現した #WAVzz では、音量は -zz に初期化されている。
2655                                                         wav.n音量 = n音量;
2656                                         }
2657                                 }
2658                                 this.n無限管理VOL[zz] = n音量;      // 次にこの WAV番号 zz を使うWAVチップが現れたら、この音量が格納されることになる。
2659                         }
2660                         //-----------------
2661                         #endregion
2662
2663                         return true;
2664                 }
2665                 private bool t入力_行解析_チップ配置(string strコマンド, string strパラメータ, string strコメント)
2666                 {
2667                         // (1) コマンドを処理。
2668
2669                         if (strコマンド.Length != 5)  // コマンドは必ず5文字であること。
2670                                 return false;
2671
2672                         #region [ n小節番号 を取得する。]
2673                         //-----------------
2674                         int n小節番号 = C変換.n小節番号の文字列3桁を数値に変換して返す(strコマンド.Substring(0, 3));
2675                         if (n小節番号 < 0)
2676                                 return false;
2677
2678                         n小節番号++;  // 先頭に空の1小節を設ける。
2679                                                                 //-----------------
2680                         #endregion
2681
2682                         #region [ nチャンネル番号 を取得する。]
2683                         //-----------------
2684                         EChannel tmpチャンネル番号 = EChannel.Invalid;
2685
2686                         // ファイルフォーマットによって処理が異なる。
2687
2688                         if (this.e種別 == EDTX種別.GDA || this.e種別 == EDTX種別.G2D)
2689                         {
2690                                 #region [ (A) GDA, G2D の場合:チャンネル文字列をDTXのチャンネル番号へ置き換える。]
2691                                 //-----------------
2692                                 string strチャンネル文字列 = strコマンド.Substring(3, 2);
2693
2694                                 foreach (STGDAPARAM param in this.stGDAParam)
2695                                 {
2696                                         if (strチャンネル文字列.Equals(param.strGDAのチャンネル文字列, StringComparison.OrdinalIgnoreCase))
2697                                         {
2698                                                 tmpチャンネル番号 = param.eDTXのチャンネル番号;
2699                                                 break;  // 置き換え成功
2700                                         }
2701                                 }
2702                                 if (tmpチャンネル番号 == EChannel.Invalid)
2703                                         return false; // 置き換え失敗
2704                                                                                                 //-----------------
2705                                 #endregion
2706                         }
2707                         else
2708                         {
2709                                 #region [ (B) その他の場合:チャンネル番号は16進数2桁。]
2710                                 //-----------------
2711                                 tmpチャンネル番号 = (EChannel)C変換.n16進数2桁の文字列を数値に変換して返す(strコマンド.Substring(3, 2));
2712
2713                                 if (tmpチャンネル番号 < 0)
2714                                         return false;
2715                                 //-----------------
2716                                 #endregion
2717                         }
2718                         //-----------------
2719                         #endregion
2720
2721
2722                         // (2) Ch.02を処理。
2723                         #region [ 小節長変更(Ch.02)は他のチャンネルとはパラメータが特殊なので、先にとっとと終わらせる。 ]
2724                         //-----------------
2725                         if (tmpチャンネル番号 == EChannel.BarLength)
2726                         {
2727                                 // 小節長倍率を取得する。
2728                                 double db小節長倍率 = 1.0;
2729                                 //if( !double.TryParse( strパラメータ, out result ) )
2730                                 if (!this.TryParse(strパラメータ, out db小節長倍率))      // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point
2731                                 {
2732                                         Trace.TraceError("小節長倍率に不正な値を指定しました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2733                                         return false;
2734                                 }
2735
2736                                 // 小節長倍率チップを一番先頭に配置する。
2737                                 this.listChip.Insert(0, new CChip(n小節番号 * 384, db小節長倍率, tmpチャンネル番号));
2738
2739                                 return true;  // 配置終了。
2740                         }
2741                         //-----------------
2742                         #endregion
2743
2744                         // (3) パラメータを処理。
2745                         if (string.IsNullOrEmpty(strパラメータ))   // パラメータはnullまたは空文字列ではないこと。
2746                                 return false;
2747
2748                         #region [ strパラメータ にオブジェクト記述を格納し、その n文字数 をカウントする。]
2749                         //-----------------
2750                         int n文字数 = 0;
2751
2752                         var sb = new StringBuilder(strパラメータ.Length);
2753
2754                         // strパラメータを先頭から1文字ずつ見ながら正規化(無効文字('_')を飛ばしたり不正な文字でエラーを出したり)し、sb へ格納する。
2755
2756                         CharEnumerator ce = strパラメータ.GetEnumerator();
2757                         while (ce.MoveNext())
2758                         {
2759                                 if (ce.Current == '_')    // '_' は無視。
2760                                         continue;
2761
2762                                 if (C変換.str36進数文字.IndexOf(ce.Current) < 0)  // オブジェクト記述は36進数文字であること。
2763                                 {
2764                                         Trace.TraceError("不正なオブジェクト指定があります。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数);
2765                                         return false;
2766                                 }
2767
2768                                 sb.Append(ce.Current);
2769                                 n文字数++;
2770                         }
2771
2772                         strパラメータ = sb.ToString(); // 正規化された文字列になりました。
2773
2774                         if ((n文字数 % 2) != 0)    // パラメータの文字数が奇数の場合、最後の1文字を無視する。
2775                                 n文字数--;
2776                         //-----------------
2777                         #endregion
2778
2779
2780                         // (4) パラメータをオブジェクト数値に分解して配置する。
2781
2782                         for (int i = 0; i < (n文字数 / 2); i++)  // 2文字で1オブジェクト数値
2783                         {
2784                                 #region [ nオブジェクト数値 を1つ取得する。'00' なら無視。]
2785                                 //-----------------
2786                                 int nオブジェクト数値 = 0;
2787
2788                                 if (tmpチャンネル番号 == EChannel.BPM)
2789                                 {
2790                                         // Ch.03 のみ 16進数2桁。
2791                                         nオブジェクト数値 = C変換.n16進数2桁の文字列を数値に変換して返す(strパラメータ.Substring(i * 2, 2));
2792                                 }
2793                                 else
2794                                 {
2795                                         // その他のチャンネルは36進数2桁。
2796                                         nオブジェクト数値 = C変換.n36進数2桁の文字列を数値に変換して返す(strパラメータ.Substring(i * 2, 2));
2797                                 }
2798
2799                                 if (nオブジェクト数値 == 0x00)
2800                                         continue;
2801                                 //-----------------
2802                                 #endregion
2803
2804                                 // オブジェクト数値に対応するチップを生成。
2805                                 var chip = new CChip((n小節番号 * 384) + ((384 * i) / (n文字数 / 2)), nオブジェクト数値, nオブジェクト数値, tmpチャンネル番号);
2806
2807                                 // 楽器パートの決定
2808                                 chip.DecideInstrumentPart();
2809
2810                                 // チップがある更新
2811                                 this.bチップがある.Drums |= chip.bDrums可視チップ;
2812                                 this.bチップがある.HHOpen |= chip[EChannel.HiHatOpen];
2813                                 this.bチップがある.Ride |= chip[EChannel.RideCymbal];
2814                                 this.bチップがある.LeftCymbal |= chip[EChannel.LeftCymbal];
2815                                 this.bチップがある.LeftPedal |= chip[EChannel.LeftPedal];
2816                                 this.bチップがある.LeftBassDrum |= chip[EChannel.LeftBassDrum];
2817                                 this.bチップがある.Guitar |= chip.bGuitar可視チップ;
2818                                 this.bチップがある.OpenGuitar |= chip[EChannel.Guitar_Open];
2819                                 this.bチップがある.Bass |= chip.bBass可視チップ;
2820                                 this.bチップがある.OpenBass |= chip[EChannel.Bass_Open];
2821                                 this.bチップがある.BGA |= chip.bBGALayer;
2822                                 this.bチップがある.Movie |= chip.bMovie;
2823                                 if (chip.bMovie)
2824                                 {
2825                                         if (chip[EChannel.MovieFull] || CDTXMania.Instance.ConfigIni.bForceScalingAVI)
2826                                         {
2827                                                 this.bMovieをFullscreen再生する = true;
2828                                         }
2829                                 }
2830
2831                                 // 空打ちチップを変換する。
2832                                 chip.ConvertNoChip();
2833
2834                                 // 無限管理オブジェクトインデックスの割当。(もしそのチップが対象であれば)
2835                                 chip.AssignInfiniteManageWAV(this.n無限管理WAV[nオブジェクト数値]);
2836                                 chip.AssignInfiniteManageBPM(this.n無限管理BPM[nオブジェクト数値]);
2837                                 chip.AdjustPlayPositionForFillin(nオブジェクト数値);
2838
2839                                 // チップを配置。
2840                                 this.listChip.Add(chip);
2841                         }
2842                         return true;
2843                 }
2844         }
2845 }