OSDN Git Service

3494f1eabcd43a5bf908e3906b66fca2e4aa8232
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / スコア、曲 / CDTX.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Runtime.InteropServices;\r
5 using System.Drawing;\r
6 using System.Diagnostics;\r
7 using System.IO;\r
8 using System.Security.Cryptography;\r
9 using System.Reflection;\r
10 using System.Globalization;\r
11 using System.Threading;\r
12 using FDK;\r
13 \r
14 namespace DTXMania\r
15 {\r
16         internal class CDTX : CActivity\r
17         {\r
18                 // 定数\r
19 \r
20                 public enum E種別 { DTX, GDA, G2D, BMS, BME, SMF }\r
21                 public enum Eレーンビットパターン\r
22                 {\r
23                         OPEN = 0,\r
24                         xxB = 1,\r
25                         xGx = 2,\r
26                         xGB = 3,\r
27                         Rxx = 4,\r
28                         RxB = 5,\r
29                         RGx = 6,\r
30                         RGB = 7\r
31                 };\r
32 \r
33 \r
34                 // クラス\r
35 \r
36                 public class CAVI : IDisposable\r
37                 {\r
38                         public CAvi avi;\r
39                         private bool bDispose済み;\r
40                         public int n番号;\r
41                         public string strコメント文 = "";\r
42                         public string strファイル名 = "";\r
43 \r
44                         public void OnDeviceCreated()\r
45                         {\r
46                                 #region [ strAVIファイル名の作成。]\r
47                                 //-----------------\r
48                                 string strAVIファイル名;\r
49                                 if( !string.IsNullOrEmpty( CDTXMania.DTX.PATH_WAV ) )\r
50                                         strAVIファイル名 = CDTXMania.DTX.PATH_WAV + this.strファイル名;\r
51                                 else\r
52                                         strAVIファイル名 = CDTXMania.DTX.strフォルダ名 + this.strファイル名;\r
53                                 //-----------------\r
54                                 #endregion\r
55 \r
56                                 if( !File.Exists( strAVIファイル名 ) )\r
57                                 {\r
58                                         Trace.TraceWarning( "ファイルが存在しません。({0})({1})", this.strコメント文, strAVIファイル名 );\r
59                                         this.avi = null;\r
60                                         return;\r
61                                 }\r
62 \r
63                                 // AVI の生成。\r
64 \r
65                                 try\r
66                                 {\r
67                                         this.avi = new CAvi( strAVIファイル名 );\r
68                                         Trace.TraceInformation( "動画を生成しました。({0})({1})({2}frames)", this.strコメント文, strAVIファイル名, this.avi.GetMaxFrameCount() );\r
69                                 }\r
70                                 catch( Exception e )\r
71                                 {\r
72                                         Trace.TraceError( e.Message );\r
73                                         Trace.TraceError( "動画の生成に失敗しました。({0})({1})", this.strコメント文, strAVIファイル名 );\r
74                                         this.avi = null;\r
75                                 }\r
76                         }\r
77                         public override string ToString()\r
78                         {\r
79                                 return string.Format( "CAVI{0}: File:{1}, Comment:{2}", CDTX.tZZ( this.n番号 ), this.strファイル名, this.strコメント文 );\r
80                         }\r
81 \r
82                         #region [ IDisposable 実装 ]\r
83                         //-----------------\r
84                         public void Dispose()\r
85                         {\r
86                                 if( this.bDispose済み )\r
87                                         return;\r
88 \r
89                                 if( this.avi != null )\r
90                                 {\r
91                                         #region [ strAVIファイル名 の作成。 ]\r
92                                         //-----------------\r
93                                         string strAVIファイル名;\r
94                                         if( !string.IsNullOrEmpty( CDTXMania.DTX.PATH_WAV ) )\r
95                                                 strAVIファイル名 = CDTXMania.DTX.PATH_WAV + this.strファイル名;\r
96                                         else\r
97                                                 strAVIファイル名 = CDTXMania.DTX.strフォルダ名 + this.strファイル名;\r
98                                         //-----------------\r
99                                         #endregion\r
100 \r
101                                         this.avi.Dispose();\r
102                                         this.avi = null;\r
103                                         \r
104                                         Trace.TraceInformation( "動画を解放しました。({0})({1})", this.strコメント文, strAVIファイル名 );\r
105                                 }\r
106 \r
107                                 this.bDispose済み = true;\r
108                         }\r
109                         //-----------------\r
110                         #endregion\r
111                 }\r
112                 public class CAVIPAN\r
113                 {\r
114                         public int nAVI番号;\r
115                         public int n移動時間ct;\r
116                         public int n番号;\r
117                         public Point pt動画側開始位置 = new Point( 0, 0 );\r
118                         public Point pt動画側終了位置 = new Point( 0, 0 );\r
119                         public Point pt表示側開始位置 = new Point( 0, 0 );\r
120                         public Point pt表示側終了位置 = new Point( 0, 0 );\r
121                         public Size sz開始サイズ = new Size( 0, 0 );\r
122                         public Size sz終了サイズ = new Size( 0, 0 );\r
123 \r
124                         public override string ToString()\r
125                         {\r
126                                 return string.Format( "CAVIPAN{0}: AVI:{14}, 開始サイズ:{1}x{2}, 終了サイズ:{3}x{4}, 動画側開始位置:{5}x{6}, 動画側終了位置:{7}x{8}, 表示側開始位置:{9}x{10}, 表示側終了位置:{11}x{12}, 移動時間:{13}ct",\r
127                                         CDTX.tZZ( this.n番号 ),\r
128                                         this.sz開始サイズ.Width, this.sz開始サイズ.Height,\r
129                                         this.sz終了サイズ.Width, this.sz終了サイズ.Height,\r
130                                         this.pt動画側開始位置.X, this.pt動画側開始位置.Y,\r
131                                         this.pt動画側終了位置.X, this.pt動画側終了位置.Y,\r
132                                         this.pt表示側開始位置.X, this.pt表示側開始位置.Y,\r
133                                         this.pt表示側終了位置.X, this.pt表示側終了位置.Y,\r
134                                         this.n移動時間ct,\r
135                                         CDTX.tZZ( this.nAVI番号 ) );\r
136                         }\r
137                 }\r
138                 public class CBGA\r
139                 {\r
140                         public int nBMP番号;\r
141                         public int n番号;\r
142                         public Point pt画像側右下座標 = new Point( 0, 0 );\r
143                         public Point pt画像側左上座標 = new Point( 0, 0 );\r
144                         public Point pt表示座標 = new Point( 0, 0 );\r
145 \r
146                         public override string ToString()\r
147                         {\r
148                                 return string.Format( "CBGA{0}, BMP:{1}, 画像側左上座標:{2}x{3}, 画像側右下座標:{4}x{5}, 表示座標:{6}x{7}",\r
149                                         CDTX.tZZ( this.n番号 ),\r
150                                         CDTX.tZZ( this.nBMP番号 ),\r
151                                         this.pt画像側左上座標.X, this.pt画像側左上座標.Y,\r
152                                         this.pt画像側右下座標.X, this.pt画像側右下座標.Y,\r
153                                         this.pt表示座標.X, this.pt表示座標.Y );\r
154                         }\r
155                 }\r
156                 public class CBGAPAN\r
157                 {\r
158                         public int nBMP番号;\r
159                         public int n移動時間ct;\r
160                         public int n番号;\r
161                         public Point pt画像側開始位置 = new Point( 0, 0 );\r
162                         public Point pt画像側終了位置 = new Point( 0, 0 );\r
163                         public Point pt表示側開始位置 = new Point( 0, 0 );\r
164                         public Point pt表示側終了位置 = new Point( 0, 0 );\r
165                         public Size sz開始サイズ = new Size( 0, 0 );\r
166                         public Size sz終了サイズ = new Size( 0, 0 );\r
167 \r
168                         public override string ToString()\r
169                         {\r
170                                 return string.Format( "CBGAPAN{0}: BMP:{14}, 開始サイズ:{1}x{2}, 終了サイズ:{3}x{4}, 画像側開始位置:{5}x{6}, 画像側終了位置:{7}x{8}, 表示側開始位置:{9}x{10}, 表示側終了位置:{11}x{12}, 移動時間:{13}ct",\r
171                                         CDTX.tZZ( this.nBMP番号 ),\r
172                                         this.sz開始サイズ.Width, this.sz開始サイズ.Height,\r
173                                         this.sz終了サイズ.Width, this.sz終了サイズ.Height,\r
174                                         this.pt画像側開始位置.X, this.pt画像側開始位置.Y,\r
175                                         this.pt画像側終了位置.X, this.pt画像側終了位置.Y,\r
176                                         this.pt表示側開始位置.X, this.pt表示側開始位置.Y,\r
177                                         this.pt表示側終了位置.X, this.pt表示側終了位置.Y,\r
178                                         this.n移動時間ct,\r
179                                         CDTX.tZZ( this.nBMP番号 ) );\r
180                         }\r
181                 }\r
182                 public class CBMP : CBMPbase, IDisposable\r
183                 {\r
184                         public CBMP()\r
185                         {\r
186                                 b黒を透過する = true;     // BMPでは、黒を透過色とする\r
187                         }\r
188                         public override void PutLog( string strテクスチャファイル名 )\r
189                         {\r
190                                 Trace.TraceInformation( "テクスチャを生成しました。({0})({1})({2}x{3})", this.strコメント文, strテクスチャファイル名, this.n幅, this.n高さ );\r
191                         }\r
192                         public override string ToString()\r
193                         {\r
194                                 return string.Format( "CBMP{0}: File:{1}, Comment:{2}", CDTX.tZZ( this.n番号 ), this.strファイル名, this.strコメント文 );\r
195                         }\r
196 \r
197                 }\r
198                 public class CBMPTEX : CBMPbase, IDisposable\r
199                 {\r
200                         public CBMPTEX()\r
201                         {\r
202                                 b黒を透過する = false;    // BMPTEXでは、透過色はαで表現する\r
203                         }\r
204                         public override void PutLog( string strテクスチャファイル名 )\r
205                         {\r
206                                 Trace.TraceInformation( "テクスチャを生成しました。({0})({1})(Gr:{2}x{3})(Tx:{4}x{5})", this.strコメント文, strテクスチャファイル名, this.tx画像.sz画像サイズ.Width, this.tx画像.sz画像サイズ.Height, this.tx画像.szテクスチャサイズ.Width, this.tx画像.szテクスチャサイズ.Height );\r
207                         }\r
208                         public override string ToString()\r
209                         {\r
210                                 return string.Format( "CBMPTEX{0}: File:{1}, Comment:{2}", CDTX.tZZ( this.n番号 ), this.strファイル名, this.strコメント文 );\r
211                         }\r
212                 }\r
213                 public class CBMPbase : IDisposable\r
214                 {\r
215                         public bool bUse;\r
216                         public int n番号;\r
217                         public string strコメント文 = "";\r
218                         public string strファイル名 = "";\r
219                         public CTexture tx画像;\r
220                         public int n高さ\r
221                         {\r
222                                 get\r
223                                 {\r
224                                         return this.tx画像.sz画像サイズ.Height;\r
225                                 }\r
226                         }\r
227                         public int n幅\r
228                         {\r
229                                 get\r
230                                 {\r
231                                         return this.tx画像.sz画像サイズ.Width;\r
232                                 }\r
233                         }\r
234                         public bool b黒を透過する;\r
235                         public Bitmap bitmap;\r
236 \r
237                         public string GetFullPathname\r
238                         {\r
239                                 get\r
240                                 {\r
241                                         if ( !string.IsNullOrEmpty( CDTXMania.DTX.PATH_WAV ) )\r
242                                                 return CDTXMania.DTX.PATH_WAV + this.strファイル名;\r
243                                         else\r
244                                                 return CDTXMania.DTX.strフォルダ名 + this.strファイル名;\r
245                                 }\r
246                         }\r
247 \r
248                         public void OnDeviceCreated()\r
249                         {\r
250                                 #region [ strテクスチャファイル名 を作成。]\r
251                                 string strテクスチャファイル名 = this.GetFullPathname;\r
252                                 #endregion\r
253 \r
254                                 if ( !File.Exists( strテクスチャファイル名 ) )\r
255                                 {\r
256                                         Trace.TraceWarning( "ファイルが存在しません。({0})({1})", this.strコメント文, strテクスチャファイル名 );\r
257                                         this.tx画像 = null;\r
258                                         return;\r
259                                 }\r
260 \r
261                                 // テクスチャを作成。\r
262                                 byte[] txData = File.ReadAllBytes( strテクスチャファイル名 );\r
263                                 this.tx画像 = CDTXMania.tテクスチャの生成( txData, b黒を透過する );\r
264 \r
265                                 if ( this.tx画像 != null )\r
266                                 {\r
267                                         // 作成成功。\r
268                                         if ( CDTXMania.ConfigIni.bLog作成解放ログ出力 )\r
269                                                 PutLog( strテクスチャファイル名 );\r
270                                         txData = null;\r
271                                         this.bUse = true;\r
272                                 }\r
273                                 else\r
274                                 {\r
275                                         // 作成失敗。\r
276                                         Trace.TraceError( "テクスチャの生成に失敗しました。({0})({1})", this.strコメント文, strテクスチャファイル名 );\r
277                                         this.tx画像 = null;\r
278                                 }\r
279                         }\r
280                         /// <summary>\r
281                         /// BGA画像のデコードをTexture()に渡す前に行う、OnDeviceCreate()\r
282                         /// </summary>\r
283                         /// <param name="bitmap">テクスチャ画像</param>\r
284                         /// <param name="strテクスチャファイル名">ファイル名</param>\r
285                         public void OnDeviceCreated( Bitmap bitmap, string strテクスチャファイル名 )\r
286                         {\r
287                                 if ( bitmap != null && b黒を透過する )\r
288                                 {\r
289                                         bitmap.MakeTransparent( Color.Black );          // 黒を透過色にする\r
290                                 }\r
291                                 this.tx画像 = CDTXMania.tテクスチャの生成( bitmap, b黒を透過する );\r
292 \r
293                                 if ( this.tx画像 != null )\r
294                                 {\r
295                                         // 作成成功。\r
296                                         if ( CDTXMania.ConfigIni.bLog作成解放ログ出力 )\r
297                                                 PutLog( strテクスチャファイル名 );\r
298                                         this.bUse = true;\r
299                                 }\r
300                                 else\r
301                                 {\r
302                                         // 作成失敗。\r
303                                         Trace.TraceError( "テクスチャの生成に失敗しました。({0})({1})", this.strコメント文, strテクスチャファイル名 );\r
304                                         this.tx画像 = null;\r
305                                 }\r
306                                 if ( bitmap != null )\r
307                                 {\r
308                                         bitmap.Dispose();\r
309                                 }\r
310                         }\r
311 \r
312                         public virtual void PutLog( string strテクスチャファイル名 )\r
313                         {\r
314                         }\r
315 \r
316                         #region [ IDisposable 実装 ]\r
317                         //-----------------\r
318                         public void Dispose()\r
319                         {\r
320                                 if ( this.bDisposed済み )\r
321                                         return;\r
322 \r
323                                 if ( this.tx画像 != null )\r
324                                 {\r
325                                         #region [ strテクスチャファイル名 を作成。]\r
326                                         //-----------------\r
327                                         string strテクスチャファイル名 = this.GetFullPathname;\r
328                                         //if( !string.IsNullOrEmpty( CDTXMania.DTX.PATH_WAV ) )\r
329                                         //    strテクスチャファイル名 = CDTXMania.DTX.PATH_WAV + this.strファイル名;\r
330                                         //else\r
331                                         //    strテクスチャファイル名 = CDTXMania.DTX.strフォルダ名 + this.strファイル名;\r
332                                         //-----------------\r
333                                         #endregion\r
334 \r
335                                         CDTXMania.tテクスチャの解放( ref this.tx画像 );\r
336 \r
337                                         if ( CDTXMania.ConfigIni.bLog作成解放ログ出力 )\r
338                                                 Trace.TraceInformation( "テクスチャを解放しました。({0})({1})", this.strコメント文, strテクスチャファイル名 );\r
339                                 }\r
340                                 this.bUse = false;\r
341 \r
342                                 this.bDisposed済み = true;\r
343                         }\r
344                         #endregion\r
345                         #region [ private ]\r
346                         //-----------------\r
347                         private bool bDisposed済み;\r
348                         //-----------------\r
349                         #endregion\r
350                 }\r
351                 public class CBPM\r
352                 {\r
353                         public double dbBPM値;\r
354                         public int n内部番号;\r
355                         public int n表記上の番号;\r
356 \r
357                         public override string ToString()\r
358                         {\r
359                                 StringBuilder builder = new StringBuilder( 0x80 );\r
360                                 if( this.n内部番号 != this.n表記上の番号 )\r
361                                 {\r
362                                         builder.Append( string.Format( "CBPM{0}(内部{1})", CDTX.tZZ( this.n表記上の番号 ), this.n内部番号 ) );\r
363                                 }\r
364                                 else\r
365                                 {\r
366                                         builder.Append( string.Format( "CBPM{0}", CDTX.tZZ( this.n表記上の番号 ) ) );\r
367                                 }\r
368                                 builder.Append( string.Format( ", BPM:{0}", this.dbBPM値 ) );\r
369                                 return builder.ToString();\r
370                         }\r
371                 }\r
372                 public class CChip : IComparable<CDTX.CChip>, ICloneable\r
373                 {\r
374                         public bool bHit;\r
375                         public bool b可視 = true;\r
376                         public double dbチップサイズ倍率 = 1.0;\r
377                         public double db実数値;\r
378                         public EAVI種別 eAVI種別;\r
379                         public EBGA種別 eBGA種別;\r
380                         public E楽器パート e楽器パート = E楽器パート.UNKNOWN;\r
381                         public int nチャンネル番号;\r
382                         public STDGBVALUE<int> nバーからの距離dot;\r
383                         public int n整数値;\r
384                         public int n整数値・内部番号;\r
385                         public int n総移動時間;\r
386                         public int n透明度 = 0xff;\r
387                         public int n発声位置;\r
388                         public int n発声時刻ms;\r
389                         public int nLag;                                // 2011.2.1 yyagi\r
390                         public CDTX.CAVI rAVI;\r
391                         public CDTX.CAVIPAN rAVIPan;\r
392                         public CDTX.CBGA rBGA;\r
393                         public CDTX.CBGAPAN rBGAPan;\r
394                         public CDTX.CBMP rBMP;\r
395                         public CDTX.CBMPTEX rBMPTEX;\r
396                         public bool bBPMチップである\r
397                         {\r
398                                 get\r
399                                 {\r
400                                         if (this.nチャンネル番号 == 3 || this.nチャンネル番号 == 8) {\r
401                                                 return true;\r
402                                         } else {\r
403                                                 return false;\r
404                                         }\r
405                                 }\r
406                         }\r
407                         public bool bWAVを使うチャンネルである\r
408                         {\r
409                                 get\r
410                                 {\r
411                                         switch( this.nチャンネル番号 )\r
412                                         {\r
413                                                 case 0x01:\r
414                                                 case 0x11:\r
415                                                 case 0x12:\r
416                                                 case 0x13:\r
417                                                 case 0x14:\r
418                                                 case 0x15:\r
419                                                 case 0x16:\r
420                                                 case 0x17:\r
421                                                 case 0x18:\r
422                                                 case 0x19:\r
423                                                 case 0x1a:\r
424                                                 case 0x1f:\r
425                                                 case 0x20:\r
426                                                 case 0x21:\r
427                                                 case 0x22:\r
428                                                 case 0x23:\r
429                                                 case 0x24:\r
430                                                 case 0x25:\r
431                                                 case 0x26:\r
432                                                 case 0x27:\r
433                                                 case 0x2f:\r
434                                                 case 0x31:\r
435                                                 case 0x32:\r
436                                                 case 0x33:\r
437                                                 case 0x34:\r
438                                                 case 0x35:\r
439                                                 case 0x36:\r
440                                                 case 0x37:\r
441                                                 case 0x38:\r
442                                                 case 0x39:\r
443                                                 case 0x3a:\r
444                                                 case 0x61:\r
445                                                 case 0x62:\r
446                                                 case 0x63:\r
447                                                 case 0x64:\r
448                                                 case 0x65:\r
449                                                 case 0x66:\r
450                                                 case 0x67:\r
451                                                 case 0x68:\r
452                                                 case 0x69:\r
453                                                 case 0x70:\r
454                                                 case 0x71:\r
455                                                 case 0x72:\r
456                                                 case 0x73:\r
457                                                 case 0x74:\r
458                                                 case 0x75:\r
459                                                 case 0x76:\r
460                                                 case 0x77:\r
461                                                 case 0x78:\r
462                                                 case 0x79:\r
463                                                 case 0x80:\r
464                                                 case 0x81:\r
465                                                 case 0x82:\r
466                                                 case 0x83:\r
467                                                 case 0x84:\r
468                                                 case 0x85:\r
469                                                 case 0x86:\r
470                                                 case 0x87:\r
471                                                 case 0x88:\r
472                                                 case 0x89:\r
473                                                 case 0x90:\r
474                                                 case 0x91:\r
475                                                 case 0x92:\r
476                                                 case 0xa0:\r
477                                                 case 0xa1:\r
478                                                 case 0xa2:\r
479                                                 case 0xa3:\r
480                                                 case 0xa4:\r
481                                                 case 0xa5:\r
482                                                 case 0xa6:\r
483                                                 case 0xa7:\r
484                                                 case 0xaf:\r
485                                                 case 0xb1:\r
486                                                 case 0xb2:\r
487                                                 case 0xb3:\r
488                                                 case 0xb4:\r
489                                                 case 0xb5:\r
490                                                 case 0xb6:\r
491                                                 case 0xb7:\r
492                                                 case 0xb8:\r
493                                                 case 0xb9:\r
494                                                 case 0xba:\r
495                                                 case 0xbb:\r
496                                                 case 0xbc:\r
497                                                         return true;\r
498                                         }\r
499                                         return false;\r
500                                 }\r
501                         }\r
502                         public bool b自動再生音チャンネルである\r
503                         {\r
504                                 get\r
505                                 {\r
506                                         int num = this.nチャンネル番号;\r
507                                         if( ( ( ( num != 1 ) && ( ( 0x61 > num ) || ( num > 0x69 ) ) ) && ( ( 0x70 > num ) || ( num > 0x79 ) ) ) && ( ( 0x80 > num ) || ( num > 0x89 ) ) )\r
508                                         {\r
509                                                 return ( ( 0x90 <= num ) && ( num <= 0x92 ) );\r
510                                         }\r
511                                         return true;\r
512                                 }\r
513                         }\r
514                         public bool bIsAutoPlayed;                                                      // 2011.6.10 yyagi\r
515                         public bool b演奏終了後も再生が続くチップである;       // #32248 2013.10.14 yyagi\r
516 \r
517                         public CChip()\r
518                         {\r
519                                 this.nバーからの距離dot = new STDGBVALUE<int>() {\r
520                                         Drums = 0,\r
521                                         Guitar = 0,\r
522                                         Bass = 0,\r
523                                 };\r
524                         }\r
525                         public void t初期化()\r
526                         {\r
527                                 this.nチャンネル番号 = 0;\r
528                                 this.n整数値 = 0;\r
529                                 this.n整数値・内部番号 = 0;\r
530                                 this.db実数値 = 0.0;\r
531                                 this.n発声位置 = 0;\r
532                                 this.n発声時刻ms = 0;\r
533                                 this.nLag = -999;\r
534                                 this.bIsAutoPlayed = false;\r
535                                 this.b演奏終了後も再生が続くチップである = false;\r
536                                 this.dbチップサイズ倍率 = 1.0;\r
537                                 this.bHit = false;\r
538                                 this.b可視 = true;\r
539                                 this.e楽器パート = E楽器パート.UNKNOWN;\r
540                                 this.n透明度 = 0xff;\r
541                                 this.nバーからの距離dot.Drums = 0;\r
542                                 this.nバーからの距離dot.Guitar = 0;\r
543                                 this.nバーからの距離dot.Bass = 0;\r
544                                 this.n総移動時間 = 0;\r
545                         }\r
546                         public override string ToString()\r
547                         {\r
548                                 string[] chToStr = \r
549                                 {\r
550                                         "??", "バックコーラス", "小節長変更", "BPM変更", "BMPレイヤ1", "??", "??", "BMPレイヤ2",\r
551                                         "BPM変更(拡張)", "??", "??", "??", "??", "??", "??", "??",\r
552                                         "??", "HHClose", "Snare", "Kick", "HiTom", "LowTom", "Cymbal", "FloorTom",\r
553                                         "HHOpen", "RideCymbal", "LeftCymbal", "", "", "", "", "ドラム歓声切替",\r
554                                         "ギターOPEN", "ギター - - B", "ギター - G -", "ギター - G B", "ギター R - -", "ギター R - B", "ギター R G -", "ギター R G B",\r
555                                         "ギターWailing", "??", "??", "??", "??", "??", "??", "ギターWailing音切替",\r
556                                         "??", "HHClose(不可視)", "Snare(不可視)", "Kick(不可視)", "HiTom(不可視)", "LowTom(不可視)", "Cymbal(不可視)", "FloorTom(不可視)",\r
557                                         "HHOpen(不可視)", "RideCymbal(不可視)", "LeftCymbal(不可視)", "??", "??", "??", "??", "??",\r
558                                         "??", "??", "??", "??", "??", "??", "??", "??", \r
559                                         "??", "??", "??", "??", "??", "??", "??", "??", \r
560                                         "小節線", "拍線", "MIDIコーラス", "フィルイン", "AVI", "BMPレイヤ3", "BMPレイヤ4", "BMPレイヤ5",\r
561                                         "BMPレイヤ6", "BMPレイヤ7", "??", "??", "??", "??", "??", "??", \r
562                                         "BMPレイヤ8", "SE01", "SE02", "SE03", "SE04", "SE05", "SE06", "SE07",\r
563                                         "SE08", "SE09", "??", "??", "??", "??", "??", "??", \r
564                                         "SE10", "SE11", "SE12", "SE13", "SE14", "SE15", "SE16", "SE17",\r
565                                         "SE18", "SE19", "??", "??", "??", "??", "??", "??", \r
566                                         "SE20", "SE21", "SE22", "SE23", "SE24", "SE25", "SE26", "SE27",\r
567                                         "SE28", "SE29", "??", "??", "??", "??", "??", "??", \r
568                                         "SE30", "SE31", "SE32", "??", "??", "??", "??", "??", \r
569                                         "??", "??", "??", "??", "??", "??", "??", "??", \r
570                                         "ベースOPEN", "ベース - - B", "ベース - G -", "ベース - G B", "ベース R - -", "ベース R - B", "ベース R G -", "ベース R G B",\r
571                                         "ベースWailing", "??", "??", "??", "??", "??", "??", "ベースWailing音切替",\r
572                                         "??", "HHClose(空うち)", "Snare(空うち)", "Kick(空うち)", "HiTom(空うち)", "LowTom(空うち)", "Cymbal(空うち)", "FloorTom(空うち)",\r
573                                         "HHOpen(空うち)", "RideCymbal(空うち)", "ギター(空打ち)", "ベース(空打ち)", "LeftCymbal(空うち)", "??", "??", "??", \r
574                                         "??", "??", "??", "??", "BGAスコープ画像切替1", "??", "??", "BGAスコープ画像切替2",\r
575                                         "??", "??", "??", "??", "??", "??", "??", "??", \r
576                                         "??", "??", "??", "??", "??", "BGAスコープ画像切替3", "BGAスコープ画像切替4", "BGAスコープ画像切替5",\r
577                                         "BGAスコープ画像切替6", "BGAスコープ画像切替7", "??", "??", "??", "??", "??", "??", \r
578                                         "BGAスコープ画像切替8"\r
579                                 };\r
580                                 return string.Format( "CChip: 位置:{0:D4}.{1:D3}, 時刻{2:D6}, Ch:{3:X2}({4}), Pn:{5}({11})(内部{6}), Pd:{7}, Sz:{8}, UseWav:{9}, Auto:{10}",\r
581                                         this.n発声位置 / 384, this.n発声位置 % 384,\r
582                                         this.n発声時刻ms,\r
583                                         this.nチャンネル番号, chToStr[ this.nチャンネル番号 ],\r
584                                         this.n整数値, this.n整数値・内部番号,\r
585                                         this.db実数値,\r
586                                         this.dbチップサイズ倍率,\r
587                                         this.bWAVを使うチャンネルである,\r
588                                         this.b自動再生音チャンネルである,\r
589                                         CDTX.tZZ( this.n整数値 ) );\r
590                         }\r
591                         public int GetDuration()\r
592                         {\r
593                                 int nDuration = 0;\r
594 \r
595                                 if ( this.bWAVを使うチャンネルである )               // WAV\r
596                                 {\r
597                                         CDTX.CWAV wc = CDTXMania.DTX.listWAV[ this.n整数値・内部番号 ];\r
598                                         nDuration = ( wc.rSound[ 0 ] == null ) ? 0 : wc.rSound[ 0 ].n総演奏時間ms;\r
599                                 }\r
600                                 else if ( this.nチャンネル番号 == 0x54 ) // AVI\r
601                                 {\r
602                                         if ( this.rAVI != null && this.rAVI.avi != null )\r
603                                         {\r
604                                                 int dwRate = (int) this.rAVI.avi.dwレート;\r
605                                                 int dwScale = (int) this.rAVI.avi.dwスケール;\r
606                                                 nDuration = (int) ( 1000.0f * dwScale / dwRate * this.rAVI.avi.GetMaxFrameCount() );\r
607 //Trace.TraceInformation( "CAVI: nDuration=" + nDuration + ", dwScale=" + dwScale + ", dwRate=" + dwRate + ", frames=" + this.rAVI.avi.GetMaxFrameCount() );\r
608                                         }\r
609                                 }\r
610 \r
611                                 return (int) ( nDuration / CDTXMania.DTX.db再生速度 );\r
612                         }\r
613 \r
614                         #region [ IComparable 実装 ]\r
615                         //-----------------\r
616                         public int CompareTo( CDTX.CChip other )\r
617                         {\r
618                                 byte[] n優先度 = new byte[] {\r
619                                         5, 5, 3, 3, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, \r
620                                         5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, \r
621                                         7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, \r
622                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
623                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
624                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
625                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
626                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
627                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
628                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
629                                         7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, \r
630                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
631                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
632                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
633                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, \r
634                                         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,\r
635                                 };\r
636 \r
637 \r
638                                 // まずは位置で比較。\r
639 \r
640                                 if( this.n発声位置 < other.n発声位置 )\r
641                                         return -1;\r
642 \r
643                                 if( this.n発声位置 > other.n発声位置 )\r
644                                         return 1;\r
645 \r
646 \r
647                                 // 位置が同じなら優先度で比較。\r
648 \r
649                                 if( n優先度[ this.nチャンネル番号 ] < n優先度[ other.nチャンネル番号 ] )\r
650                                         return -1;\r
651 \r
652                                 if( n優先度[ this.nチャンネル番号 ] > n優先度[ other.nチャンネル番号 ] )\r
653                                         return 1;\r
654 \r
655 \r
656                                 // 位置も優先度も同じなら同じと返す。\r
657 \r
658                                 return 0;\r
659                         }\r
660                         //-----------------\r
661                         #endregion\r
662                         /// <summary>\r
663                         /// shallow copyです。\r
664                         /// </summary>\r
665                         /// <returns></returns>\r
666                         public object Clone()\r
667                         {\r
668                                 return MemberwiseClone();\r
669                         }\r
670                 }\r
671                 public class CWAV : IDisposable\r
672                 {\r
673                         public bool bBGMとして使う;\r
674                         public List<int> listこのWAVを使用するチャンネル番号の集合 = new List<int>( 16 );\r
675                         public int nチップサイズ = 100;\r
676                         public int n位置;\r
677                         public long[] n一時停止時刻 = new long[ CDTXMania.ConfigIni.nPoliphonicSounds ];  // 4\r
678                         public int n音量 = 100;\r
679                         public int n現在再生中のサウンド番号;\r
680                         public long[] n再生開始時刻 = new long[ CDTXMania.ConfigIni.nPoliphonicSounds ];  // 4\r
681                         public int n内部番号;\r
682                         public int n表記上の番号;\r
683                         public CSound[] rSound = new CSound[ CDTXMania.ConfigIni.nPoliphonicSounds ];           // 4\r
684                         public string strコメント文 = "";\r
685                         public string strファイル名 = "";\r
686                         public bool bBGMとして使わない\r
687                         {\r
688                                 get\r
689                                 {\r
690                                         return !this.bBGMとして使う;\r
691                                 }\r
692                                 set\r
693                                 {\r
694                                         this.bBGMとして使う = !value;\r
695                                 }\r
696                         }\r
697                         public bool bIsBassSound = false;\r
698                         public bool bIsGuitarSound = false;\r
699                         public bool bIsDrumsSound = false;\r
700                         public bool bIsSESound = false;\r
701                         public bool bIsBGMSound = false;\r
702 \r
703                         public override string ToString()\r
704                         {\r
705                                 var sb = new StringBuilder( 128 );\r
706                                 \r
707                                 if( this.n表記上の番号 == this.n内部番号 )\r
708                                 {\r
709                                         sb.Append( string.Format( "CWAV{0}: ", CDTX.tZZ( this.n表記上の番号 ) ) );\r
710                                 }\r
711                                 else\r
712                                 {\r
713                                         sb.Append( string.Format( "CWAV{0}(内部{1}): ", CDTX.tZZ( this.n表記上の番号 ), this.n内部番号 ) );\r
714                                 }\r
715                                 sb.Append( string.Format( "音量:{0}, 位置:{1}, サイズ:{2}, BGM:{3}, File:{4}, Comment:{5}", this.n音量, this.n位置, this.nチップサイズ, this.bBGMとして使う ? 'Y' : 'N', this.strファイル名, this.strコメント文 ) );\r
716                                 \r
717                                 return sb.ToString();\r
718                         }\r
719 \r
720                         #region [ Dispose-Finalize パターン実装 ]\r
721                         //-----------------\r
722                         public void Dispose()\r
723                         {\r
724                                 this.Dispose( true );\r
725                                 GC.SuppressFinalize( this );\r
726                         }\r
727                         public void Dispose( bool bManagedリソースの解放も行う )\r
728                         {\r
729                                 if( this.bDisposed済み )\r
730                                         return;\r
731 \r
732                                 if( bManagedリソースの解放も行う )\r
733                                 {\r
734                                         for ( int i = 0; i < CDTXMania.ConfigIni.nPoliphonicSounds; i++ )       // 4\r
735                                         {\r
736                                                 if( this.rSound[ i ] != null )\r
737                                                         CDTXMania.Sound管理.tサウンドを破棄する( this.rSound[ i ] );\r
738                                                 this.rSound[ i ] = null;\r
739 \r
740                                                 if( ( i == 0 ) && CDTXMania.ConfigIni.bLog作成解放ログ出力 )\r
741                                                         Trace.TraceInformation( "サウンドを解放しました。({0})({1})", this.strコメント文, this.strファイル名 );\r
742                                         }\r
743                                 }\r
744 \r
745                                 this.bDisposed済み = true;\r
746                         }\r
747                         ~CWAV()\r
748                         {\r
749                                 this.Dispose( false );\r
750                         }\r
751                         //-----------------\r
752                         #endregion\r
753 \r
754                         #region [ private ]\r
755                         //-----------------\r
756                         private bool bDisposed済み;\r
757                         //-----------------\r
758                         #endregion\r
759                 }\r
760                 \r
761 \r
762                 // 構造体\r
763 \r
764                 public struct STLANEINT\r
765                 {\r
766                         public int HH;\r
767                         public int SD;\r
768                         public int BD;\r
769                         public int HT;\r
770                         public int LT;\r
771                         public int CY;\r
772                         public int FT;\r
773                         public int HHO;\r
774                         public int RD;\r
775                         public int LC;\r
776 \r
777                         public int Drums\r
778                         {\r
779                                 get\r
780                                 {\r
781                                         return this.HH + this.SD + this.BD + this.HT + this.LT + this.CY + this.FT + this.HHO + this.RD + this.LC;\r
782                                 }\r
783                         }\r
784                         public int Guitar;\r
785                         public int Bass;\r
786 \r
787                         public int this[ int index ]\r
788                         {\r
789                                 get\r
790                                 {\r
791                                         switch( index )\r
792                                         {\r
793                                                 case 0:\r
794                                                         return this.HH;\r
795 \r
796                                                 case 1:\r
797                                                         return this.SD;\r
798 \r
799                                                 case 2:\r
800                                                         return this.BD;\r
801 \r
802                                                 case 3:\r
803                                                         return this.HT;\r
804 \r
805                                                 case 4:\r
806                                                         return this.LT;\r
807 \r
808                                                 case 5:\r
809                                                         return this.CY;\r
810 \r
811                                                 case 6:\r
812                                                         return this.FT;\r
813 \r
814                                                 case 7:\r
815                                                         return this.HHO;\r
816 \r
817                                                 case 8:\r
818                                                         return this.RD;\r
819 \r
820                                                 case 9:\r
821                                                         return this.LC;\r
822 \r
823                                                 case 10:\r
824                                                         return this.Guitar;\r
825 \r
826                                                 case 11:\r
827                                                         return this.Bass;\r
828                                         }\r
829                                         throw new IndexOutOfRangeException();\r
830                                 }\r
831                                 set\r
832                                 {\r
833                                         if( value < 0 )\r
834                                         {\r
835                                                 throw new ArgumentOutOfRangeException();\r
836                                         }\r
837                                         switch( index )\r
838                                         {\r
839                                                 case 0:\r
840                                                         this.HH = value;\r
841                                                         return;\r
842 \r
843                                                 case 1:\r
844                                                         this.SD = value;\r
845                                                         return;\r
846 \r
847                                                 case 2:\r
848                                                         this.BD = value;\r
849                                                         return;\r
850 \r
851                                                 case 3:\r
852                                                         this.HT = value;\r
853                                                         return;\r
854 \r
855                                                 case 4:\r
856                                                         this.LT = value;\r
857                                                         return;\r
858 \r
859                                                 case 5:\r
860                                                         this.CY = value;\r
861                                                         return;\r
862 \r
863                                                 case 6:\r
864                                                         this.FT = value;\r
865                                                         return;\r
866 \r
867                                                 case 7:\r
868                                                         this.HHO = value;\r
869                                                         return;\r
870 \r
871                                                 case 8:\r
872                                                         this.RD = value;\r
873                                                         return;\r
874 \r
875                                                 case 9:\r
876                                                         this.LC = value;\r
877                                                         return;\r
878 \r
879                                                 case 10:\r
880                                                         this.Guitar = value;\r
881                                                         return;\r
882 \r
883                                                 case 11:\r
884                                                         this.Bass = value;\r
885                                                         return;\r
886                                         }\r
887                                         throw new IndexOutOfRangeException();\r
888                                 }\r
889                         }\r
890                 }\r
891                 public struct STRESULT\r
892                 {\r
893                         public string SS;\r
894                         public string S;\r
895                         public string A;\r
896                         public string B;\r
897                         public string C;\r
898                         public string D;\r
899                         public string E;\r
900 \r
901                         public string this[ int index ]\r
902                         {\r
903                                 get\r
904                                 {\r
905                                         switch( index )\r
906                                         {\r
907                                                 case 0:\r
908                                                         return this.SS;\r
909 \r
910                                                 case 1:\r
911                                                         return this.S;\r
912 \r
913                                                 case 2:\r
914                                                         return this.A;\r
915 \r
916                                                 case 3:\r
917                                                         return this.B;\r
918 \r
919                                                 case 4:\r
920                                                         return this.C;\r
921 \r
922                                                 case 5:\r
923                                                         return this.D;\r
924 \r
925                                                 case 6:\r
926                                                         return this.E;\r
927                                         }\r
928                                         throw new IndexOutOfRangeException();\r
929                                 }\r
930                                 set\r
931                                 {\r
932                                         switch( index )\r
933                                         {\r
934                                                 case 0:\r
935                                                         this.SS = value;\r
936                                                         return;\r
937 \r
938                                                 case 1:\r
939                                                         this.S = value;\r
940                                                         return;\r
941 \r
942                                                 case 2:\r
943                                                         this.A = value;\r
944                                                         return;\r
945 \r
946                                                 case 3:\r
947                                                         this.B = value;\r
948                                                         return;\r
949 \r
950                                                 case 4:\r
951                                                         this.C = value;\r
952                                                         return;\r
953 \r
954                                                 case 5:\r
955                                                         this.D = value;\r
956                                                         return;\r
957 \r
958                                                 case 6:\r
959                                                         this.E = value;\r
960                                                         return;\r
961                                         }\r
962                                         throw new IndexOutOfRangeException();\r
963                                 }\r
964                         }\r
965                 }\r
966                 public struct STチップがある\r
967                 {\r
968                         public bool Drums;\r
969                         public bool Guitar;\r
970                         public bool Bass;\r
971 \r
972                         public bool HHOpen;\r
973                         public bool Ride;\r
974                         public bool LeftCymbal;\r
975                         public bool OpenGuitar;\r
976                         public bool OpenBass;\r
977                         \r
978                         public bool this[ int index ]\r
979                         {\r
980                                 get\r
981                                 {\r
982                                         switch( index )\r
983                                         {\r
984                                                 case 0:\r
985                                                         return this.Drums;\r
986 \r
987                                                 case 1:\r
988                                                         return this.Guitar;\r
989 \r
990                                                 case 2:\r
991                                                         return this.Bass;\r
992 \r
993                                                 case 3:\r
994                                                         return this.HHOpen;\r
995 \r
996                                                 case 4:\r
997                                                         return this.Ride;\r
998 \r
999                                                 case 5:\r
1000                                                         return this.LeftCymbal;\r
1001 \r
1002                                                 case 6:\r
1003                                                         return this.OpenGuitar;\r
1004 \r
1005                                                 case 7:\r
1006                                                         return this.OpenBass;\r
1007                                         }\r
1008                                         throw new IndexOutOfRangeException();\r
1009                                 }\r
1010                                 set\r
1011                                 {\r
1012                                         switch( index )\r
1013                                         {\r
1014                                                 case 0:\r
1015                                                         this.Drums = value;\r
1016                                                         return;\r
1017 \r
1018                                                 case 1:\r
1019                                                         this.Guitar = value;\r
1020                                                         return;\r
1021 \r
1022                                                 case 2:\r
1023                                                         this.Bass = value;\r
1024                                                         return;\r
1025 \r
1026                                                 case 3:\r
1027                                                         this.HHOpen = value;\r
1028                                                         return;\r
1029 \r
1030                                                 case 4:\r
1031                                                         this.Ride = value;\r
1032                                                         return;\r
1033 \r
1034                                                 case 5:\r
1035                                                         this.LeftCymbal = value;\r
1036                                                         return;\r
1037 \r
1038                                                 case 6:\r
1039                                                         this.OpenGuitar = value;\r
1040                                                         return;\r
1041 \r
1042                                                 case 7:\r
1043                                                         this.OpenBass = value;\r
1044                                                         return;\r
1045                                         }\r
1046                                         throw new IndexOutOfRangeException();\r
1047                                 }\r
1048                         }\r
1049                 }\r
1050 \r
1051 \r
1052                 // プロパティ\r
1053 \r
1054                 public int nBGMAdjust\r
1055                 {\r
1056                         get; \r
1057                         private set;\r
1058                 }\r
1059                 public string ARTIST;\r
1060                 public string BACKGROUND;\r
1061                 public string BACKGROUND_GR;\r
1062                 public double BASEBPM;\r
1063                 public bool BLACKCOLORKEY;\r
1064                 public double BPM;\r
1065                 public STチップがある bチップがある;\r
1066                 public string COMMENT;\r
1067                 public double db再生速度;\r
1068                 public E種別 e種別;\r
1069                 public string GENRE;\r
1070                 public bool HIDDENLEVEL;\r
1071                 public STDGBVALUE<int> LEVEL;\r
1072                 public Dictionary<int, CAVI> listAVI;\r
1073                 public Dictionary<int, CAVIPAN> listAVIPAN;\r
1074                 public Dictionary<int, CBGA> listBGA;\r
1075                 public Dictionary<int, CBGAPAN> listBGAPAN;\r
1076                 public Dictionary<int, CBMP> listBMP;\r
1077                 public Dictionary<int, CBMPTEX> listBMPTEX;\r
1078                 public Dictionary<int, CBPM> listBPM;\r
1079                 public List<CChip> listChip;\r
1080                 public Dictionary<int, CWAV> listWAV;\r
1081                 public string MIDIFILE;\r
1082                 public bool MIDINOTE;\r
1083                 public int MIDIレベル;\r
1084                 public STLANEINT n可視チップ数;\r
1085                 public const int n最大音数 = 4;\r
1086                 public const int n小節の解像度 = 384;\r
1087                 public string PANEL;\r
1088                 public string PATH_WAV;\r
1089                 public string PREIMAGE;\r
1090                 public string PREMOVIE;\r
1091                 public string PREVIEW;\r
1092                 public STRESULT RESULTIMAGE;\r
1093                 public STRESULT RESULTMOVIE;\r
1094                 public STRESULT RESULTSOUND;\r
1095                 public string SOUND_AUDIENCE;\r
1096                 public string SOUND_FULLCOMBO;\r
1097                 public string SOUND_NOWLOADING;\r
1098                 public string SOUND_STAGEFAILED;\r
1099                 public string STAGEFILE;\r
1100                 public string strハッシュofDTXファイル;\r
1101                 public string strファイル名;\r
1102                 public string strファイル名の絶対パス;\r
1103                 public string strフォルダ名;\r
1104                 public string TITLE;\r
1105                 public double dbDTXVPlaySpeed;\r
1106 \r
1107 #if TEST_NOTEOFFMODE\r
1108                 public STLANEVALUE<bool> b演奏で直前の音を消音する;\r
1109 //              public bool bHH演奏で直前のHHを消音する;\r
1110 //              public bool bGUITAR演奏で直前のGUITARを消音する;\r
1111 //              public bool bBASS演奏で直前のBASSを消音する;\r
1112 #endif\r
1113                 // コンストラクタ\r
1114 \r
1115                 public CDTX()\r
1116                 {\r
1117                         this.TITLE = "";\r
1118                         this.ARTIST = "";\r
1119                         this.COMMENT = "";\r
1120                         this.PANEL = "";\r
1121                         this.GENRE = "";\r
1122                         this.PREVIEW = "";\r
1123                         this.PREIMAGE = "";\r
1124                         this.PREMOVIE = "";\r
1125                         this.STAGEFILE = "";\r
1126                         this.BACKGROUND = "";\r
1127                         this.BACKGROUND_GR = "";\r
1128                         this.PATH_WAV = "";\r
1129                         this.MIDIFILE = "";\r
1130                         this.SOUND_STAGEFAILED = "";\r
1131                         this.SOUND_FULLCOMBO = "";\r
1132                         this.SOUND_NOWLOADING = "";\r
1133                         this.SOUND_AUDIENCE = "";\r
1134                         this.BPM = 120.0;\r
1135                         this.BLACKCOLORKEY = true;\r
1136                         STDGBVALUE<int> stdgbvalue = new STDGBVALUE<int>();\r
1137                         stdgbvalue.Drums = 0;\r
1138                         stdgbvalue.Guitar = 0;\r
1139                         stdgbvalue.Bass = 0;\r
1140                         this.LEVEL = stdgbvalue;\r
1141                         for (int i = 0; i < 7; i++) {\r
1142                                 this.RESULTIMAGE[i] = "";\r
1143                                 this.RESULTMOVIE[i] = "";\r
1144                                 this.RESULTSOUND[i] = "";\r
1145                         }\r
1146                         this.db再生速度 = 1.0;\r
1147                         this.strハッシュofDTXファイル = "";\r
1148                         this.bチップがある = new STチップがある();\r
1149                         this.bチップがある.Drums = false;\r
1150                         this.bチップがある.Guitar = false;\r
1151                         this.bチップがある.Bass = false;\r
1152                         this.bチップがある.HHOpen = false;\r
1153                         this.bチップがある.Ride = false;\r
1154                         this.bチップがある.LeftCymbal = false;\r
1155                         this.bチップがある.OpenGuitar = false;\r
1156                         this.bチップがある.OpenBass = false;\r
1157                         this.strファイル名 = "";\r
1158                         this.strフォルダ名 = "";\r
1159                         this.strファイル名の絶対パス = "";\r
1160                         this.n無限管理WAV = new int[ 36 * 36 ];\r
1161                         this.n無限管理BPM = new int[ 36 * 36 ];\r
1162                         this.n無限管理VOL = new int[ 36 * 36 ];\r
1163                         this.n無限管理PAN = new int[ 36 * 36 ];\r
1164                         this.n無限管理SIZE = new int[ 36 * 36 ];\r
1165                         this.nRESULTIMAGE用優先順位 = new int[ 7 ];\r
1166                         this.nRESULTMOVIE用優先順位 = new int[ 7 ];\r
1167                         this.nRESULTSOUND用優先順位 = new int[ 7 ];\r
1168 \r
1169                         #region [ 2011.1.1 yyagi GDA->DTX変換テーブル リファクタ後 ]\r
1170                         STGDAPARAM[] stgdaparamArray = new STGDAPARAM[] {               // GDA->DTX conversion table\r
1171                                 new STGDAPARAM("TC", 0x03),     new STGDAPARAM("BL", 0x02),     new STGDAPARAM("GS", 0x29),\r
1172                                 new STGDAPARAM("DS", 0x30),     new STGDAPARAM("FI", 0x53),     new STGDAPARAM("HH", 0x11),\r
1173                                 new STGDAPARAM("SD", 0x12),     new STGDAPARAM("BD", 0x13),     new STGDAPARAM("HT", 0x14),\r
1174                                 new STGDAPARAM("LT", 0x15),     new STGDAPARAM("CY", 0x16),     new STGDAPARAM("G1", 0x21),\r
1175                                 new STGDAPARAM("G2", 0x22),     new STGDAPARAM("G3", 0x23),     new STGDAPARAM("G4", 0x24),\r
1176                                 new STGDAPARAM("G5", 0x25),     new STGDAPARAM("G6", 0x26),     new STGDAPARAM("G7", 0x27),\r
1177                                 new STGDAPARAM("GW", 0x28),     new STGDAPARAM("01", 0x61),     new STGDAPARAM("02", 0x62),\r
1178                                 new STGDAPARAM("03", 0x63),     new STGDAPARAM("04", 0x64),     new STGDAPARAM("05", 0x65),\r
1179                                 new STGDAPARAM("06", 0x66),     new STGDAPARAM("07", 0x67),     new STGDAPARAM("08", 0x68),\r
1180                                 new STGDAPARAM("09", 0x69),     new STGDAPARAM("0A", 0x70),     new STGDAPARAM("0B", 0x71),\r
1181                                 new STGDAPARAM("0C", 0x72),     new STGDAPARAM("0D", 0x73),     new STGDAPARAM("0E", 0x74),\r
1182                                 new STGDAPARAM("0F", 0x75),     new STGDAPARAM("10", 0x76),     new STGDAPARAM("11", 0x77),\r
1183                                 new STGDAPARAM("12", 0x78),     new STGDAPARAM("13", 0x79),     new STGDAPARAM("14", 0x80),\r
1184                                 new STGDAPARAM("15", 0x81),     new STGDAPARAM("16", 0x82),     new STGDAPARAM("17", 0x83),\r
1185                                 new STGDAPARAM("18", 0x84),     new STGDAPARAM("19", 0x85),     new STGDAPARAM("1A", 0x86),\r
1186                                 new STGDAPARAM("1B", 0x87),     new STGDAPARAM("1C", 0x88),     new STGDAPARAM("1D", 0x89),\r
1187                                 new STGDAPARAM("1E", 0x90),     new STGDAPARAM("1F", 0x91),     new STGDAPARAM("20", 0x92),\r
1188                                 new STGDAPARAM("B1", 0xA1),     new STGDAPARAM("B2", 0xA2),     new STGDAPARAM("B3", 0xA3),\r
1189                                 new STGDAPARAM("B4", 0xA4),     new STGDAPARAM("B5", 0xA5),     new STGDAPARAM("B6", 0xA6),\r
1190                                 new STGDAPARAM("B7", 0xA7),     new STGDAPARAM("BW", 0xA8),     new STGDAPARAM("G0", 0x20),\r
1191                                 new STGDAPARAM("B0", 0xA0)\r
1192                         };\r
1193                         this.stGDAParam = stgdaparamArray;\r
1194                         #endregion\r
1195                         this.nBGMAdjust = 0;\r
1196                         this.nPolyphonicSounds = CDTXMania.ConfigIni.nPoliphonicSounds;\r
1197                         this.dbDTXVPlaySpeed = 1.0f;\r
1198 \r
1199 #if TEST_NOTEOFFMODE\r
1200                         this.bHH演奏で直前のHHを消音する = true;\r
1201                         this.bGUITAR演奏で直前のGUITARを消音する = true;\r
1202                         this.bBASS演奏で直前のBASSを消音する = true;\r
1203 #endif\r
1204         \r
1205                 }\r
1206                 public CDTX( string str全入力文字列 )\r
1207                         : this()\r
1208                 {\r
1209                         this.On活性化();\r
1210                         this.t入力・全入力文字列から( str全入力文字列 );\r
1211                 }\r
1212                 public CDTX( string strファイル名, bool bヘッダのみ )\r
1213                         : this()\r
1214                 {\r
1215                         this.On活性化();\r
1216                         this.t入力( strファイル名, bヘッダのみ );\r
1217                 }\r
1218                 public CDTX( string str全入力文字列, double db再生速度, int nBGMAdjust )\r
1219                         : this()\r
1220                 {\r
1221                         this.On活性化();\r
1222                         this.t入力・全入力文字列から( str全入力文字列, db再生速度, nBGMAdjust );\r
1223                 }\r
1224                 public CDTX( string strファイル名, bool bヘッダのみ, double db再生速度, int nBGMAdjust )\r
1225                         : this()\r
1226                 {\r
1227                         this.On活性化();\r
1228                         this.t入力( strファイル名, bヘッダのみ, db再生速度, nBGMAdjust );\r
1229                 }\r
1230 \r
1231 \r
1232                 // メソッド\r
1233 \r
1234                 public int nモニタを考慮した音量( E楽器パート part )\r
1235                 {\r
1236                         CConfigIni configIni = CDTXMania.ConfigIni;\r
1237                         switch( part )\r
1238                         {\r
1239                                 case E楽器パート.DRUMS:\r
1240                                         if( configIni.b演奏音を強調する.Drums )\r
1241                                         {\r
1242                                                 return configIni.n自動再生音量;\r
1243                                         }\r
1244                                         return configIni.n手動再生音量;\r
1245 \r
1246                                 case E楽器パート.GUITAR:\r
1247                                         if( configIni.b演奏音を強調する.Guitar )\r
1248                                         {\r
1249                                                 return configIni.n自動再生音量;\r
1250                                         }\r
1251                                         return configIni.n手動再生音量;\r
1252 \r
1253                                 case E楽器パート.BASS:\r
1254                                         if( configIni.b演奏音を強調する.Bass )\r
1255                                         {\r
1256                                                 return configIni.n自動再生音量;\r
1257                                         }\r
1258                                         return configIni.n手動再生音量;\r
1259                         }\r
1260                         if( ( !configIni.b演奏音を強調する.Drums && !configIni.b演奏音を強調する.Guitar ) && !configIni.b演奏音を強調する.Bass )\r
1261                         {\r
1262                                 return configIni.n手動再生音量;\r
1263                         }\r
1264                         return configIni.n自動再生音量;\r
1265                 }\r
1266                 public void tAVIの読み込み()\r
1267                 {\r
1268                         if( this.listAVI != null )\r
1269                         {\r
1270                                 foreach( CAVI cavi in this.listAVI.Values )\r
1271                                 {\r
1272                                         cavi.OnDeviceCreated();\r
1273                                 }\r
1274                         }\r
1275                         if( !this.bヘッダのみ )\r
1276                         {\r
1277                                 foreach( CChip chip in this.listChip )\r
1278                                 {\r
1279                                         if( chip.nチャンネル番号 == 0x54 )\r
1280                                         {\r
1281                                                 chip.eAVI種別 = EAVI種別.Unknown;\r
1282                                                 chip.rAVI = null;\r
1283                                                 chip.rAVIPan = null;\r
1284                                                 if( this.listAVIPAN.ContainsKey( chip.n整数値 ) )\r
1285                                                 {\r
1286                                                         CAVIPAN cavipan = this.listAVIPAN[ chip.n整数値 ];\r
1287                                                         if( this.listAVI.ContainsKey( cavipan.nAVI番号 ) && ( this.listAVI[ cavipan.nAVI番号 ].avi != null ) )\r
1288                                                         {\r
1289                                                                 chip.eAVI種別 = EAVI種別.AVIPAN;\r
1290                                                                 chip.rAVI = this.listAVI[ cavipan.nAVI番号 ];\r
1291                                                                 chip.rAVIPan = cavipan;\r
1292                                                                 continue;\r
1293                                                         }\r
1294                                                 }\r
1295                                                 if( this.listAVI.ContainsKey( chip.n整数値 ) && ( this.listAVI[ chip.n整数値 ].avi != null ) )\r
1296                                                 {\r
1297                                                         chip.eAVI種別 = EAVI種別.AVI;\r
1298                                                         chip.rAVI = this.listAVI[ chip.n整数値 ];\r
1299                                                 }\r
1300                                         }\r
1301                                 }\r
1302                         }\r
1303                 }\r
1304                 #region [ BMP/BMPTEXの並列読み込み・デコード用メソッド ]\r
1305                 delegate void BackgroundBMPLoadAll( Dictionary<int, CBMP> listB );\r
1306                 static BackgroundBMPLoadAll backgroundBMPLoadAll = new BackgroundBMPLoadAll( BMPLoadAll );\r
1307                 delegate void BackgroundBMPTEXLoadAll( Dictionary<int, CBMPTEX> listB );\r
1308                 static BackgroundBMPTEXLoadAll backgroundBMPTEXLoadAll = new BackgroundBMPTEXLoadAll( BMPTEXLoadAll );\r
1309                 private static void LoadTexture( CBMPbase cbmp )                                                // バックグラウンドスレッドで動作する、ファイル読み込み部\r
1310                 {\r
1311                         string filename = cbmp.GetFullPathname;\r
1312                         if ( !File.Exists( filename ) )\r
1313                         {\r
1314                                 Trace.TraceWarning( "ファイルが存在しません。({0})", filename );\r
1315                                 cbmp.bitmap = null;\r
1316                                 return;\r
1317                         }\r
1318                         cbmp.bitmap = new Bitmap( filename );\r
1319                 }\r
1320                 private static void BMPLoadAll( Dictionary<int, CBMP> listB )   // バックグラウンドスレッドで、テクスチャファイルをひたすら読み込んではキューに追加する\r
1321                 {\r
1322                         //Trace.TraceInformation( "Back: ThreadID(BMPLoad)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + listB.Count  );\r
1323                         foreach ( CBMPbase cbmp in listB.Values )\r
1324                         {\r
1325                                 LoadTexture( cbmp );\r
1326                                 lock ( lockQueue )\r
1327                                 {\r
1328                                         queueCBMPbaseDone.Enqueue( cbmp );\r
1329                                         //  Trace.TraceInformation( "Back: Enqueued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
1330                                 }\r
1331                                 if ( queueCBMPbaseDone.Count > 8 )\r
1332                                 {\r
1333                                         Thread.Sleep( 10 );\r
1334                                 }\r
1335                         }\r
1336                 }\r
1337                 private static void BMPTEXLoadAll( Dictionary<int, CBMPTEX> listB )     // ダサい実装だが、Dictionary<>の中には手を出せず、妥協した\r
1338                 {\r
1339                         //Trace.TraceInformation( "Back: ThreadID(BMPLoad)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + listB.Count  );\r
1340                         foreach ( CBMPbase cbmp in listB.Values )\r
1341                         {\r
1342                                 LoadTexture( cbmp );\r
1343                                 lock ( lockQueue )\r
1344                                 {\r
1345                                         queueCBMPbaseDone.Enqueue( cbmp );\r
1346                                         //  Trace.TraceInformation( "Back: Enqueued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
1347                                 }\r
1348                                 if ( queueCBMPbaseDone.Count > 8 )\r
1349                                 {\r
1350                                         Thread.Sleep( 10 );\r
1351                                 }\r
1352                         }\r
1353                 }\r
1354 \r
1355                 private static Queue<CBMPbase> queueCBMPbaseDone = new Queue<CBMPbase>();\r
1356                 private static object lockQueue = new object();\r
1357                 private static int nLoadDone;\r
1358                 #endregion\r
1359 \r
1360                 public void tBMP_BMPTEXの読み込み()\r
1361                 {\r
1362                         #region [ CPUコア数の取得 ]\r
1363                         CWin32.SYSTEM_INFO sysInfo = new CWin32.SYSTEM_INFO();\r
1364                         CWin32.GetSystemInfo( ref sysInfo );\r
1365                         int nCPUCores = (int) sysInfo.dwNumberOfProcessors;\r
1366                         #endregion\r
1367                         #region [ BMP読み込み ]\r
1368                         if ( this.listBMP != null )\r
1369                         {\r
1370                                 if ( nCPUCores <= 1 )\r
1371                                 {\r
1372                                         #region [ シングルスレッドで逐次読み出し・デコード・テクスチャ定義 ]\r
1373                                         foreach ( CBMP cbmp in this.listBMP.Values )\r
1374                                         {\r
1375                                                 cbmp.OnDeviceCreated();\r
1376                                         }\r
1377                                         #endregion\r
1378                                 }\r
1379                                 else\r
1380                                 {\r
1381                                         #region [ メインスレッド(テクスチャ定義)とバックグラウンドスレッド(読み出し・デコード)を並列動作させ高速化 ]\r
1382                                         //Trace.TraceInformation( "Main: ThreadID(Main)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + this.listBMP.Count );\r
1383                                         nLoadDone = 0;\r
1384                                         backgroundBMPLoadAll.BeginInvoke( listBMP, null, null );\r
1385 \r
1386                                         // t.Priority = ThreadPriority.Lowest;\r
1387                                         // t.Start( listBMP );\r
1388                                         int c = listBMP.Count;\r
1389                                         while ( nLoadDone < c )\r
1390                                         {\r
1391                                                 if ( queueCBMPbaseDone.Count > 0 )\r
1392                                                 {\r
1393                                                         CBMP cbmp;\r
1394                                                         //Trace.TraceInformation( "Main: Lock Begin for dequeue1." );\r
1395                                                         lock ( lockQueue )\r
1396                                                         {\r
1397                                                                 cbmp = (CBMP) queueCBMPbaseDone.Dequeue();\r
1398                                                                 //  Trace.TraceInformation( "Main: Dequeued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
1399                                                         }\r
1400                                                         cbmp.OnDeviceCreated( cbmp.bitmap, cbmp.GetFullPathname );\r
1401                                                         nLoadDone++;\r
1402                                                         //Trace.TraceInformation( "Main: OnDeviceCreated: " + cbmp.strファイル名 );\r
1403                                                 }\r
1404                                                 else\r
1405                                                 {\r
1406                                                         //Trace.TraceInformation( "Main: Sleeped.");\r
1407                                                         Thread.Sleep( 5 );      // WaitOneのイベント待ちにすると、メインスレッド処理中に2個以上イベント完了したときにそれを正しく検出できなくなるので、\r
1408                                                 }                                               // ポーリングに逃げてしまいました。\r
1409                                         }\r
1410                                         #endregion\r
1411                                 }\r
1412                         }\r
1413                         #endregion\r
1414                         #region [ BMPTEX読み込み ]\r
1415                         if ( this.listBMPTEX != null )\r
1416                         {\r
1417                                 if ( nCPUCores <= 1 )\r
1418                                 {\r
1419                                         #region [ シングルスレッドで逐次読み出し・デコード・テクスチャ定義 ]\r
1420                                         foreach ( CBMPTEX cbmptex in this.listBMPTEX.Values )\r
1421                                         {\r
1422                                                 cbmptex.OnDeviceCreated();\r
1423                                         }\r
1424                                         #endregion\r
1425                                 }\r
1426                                 else\r
1427                                 {\r
1428                                         #region [ メインスレッド(テクスチャ定義)とバックグラウンドスレッド(読み出し・デコード)を並列動作させ高速化 ]\r
1429                                         //Trace.TraceInformation( "Main: ThreadID(Main)=" + Thread.CurrentThread.ManagedThreadId + ", listCount=" + this.listBMP.Count );\r
1430                                         nLoadDone = 0;\r
1431                                         backgroundBMPTEXLoadAll.BeginInvoke( listBMPTEX, null, null );\r
1432                                         int c = listBMPTEX.Count;\r
1433                                         while ( nLoadDone < c )\r
1434                                         {\r
1435                                                 if ( queueCBMPbaseDone.Count > 0 )\r
1436                                                 {\r
1437                                                         CBMPTEX cbmptex;\r
1438                                                         //Trace.TraceInformation( "Main: Lock Begin for dequeue1." );\r
1439                                                         lock ( lockQueue )\r
1440                                                         {\r
1441                                                                 cbmptex = (CBMPTEX) queueCBMPbaseDone.Dequeue();\r
1442                                                                 //  Trace.TraceInformation( "Main: Dequeued(" + queueCBMPbaseDone.Count + "): " + cbmp.strファイル名 );\r
1443                                                         }\r
1444                                                         cbmptex.OnDeviceCreated( cbmptex.bitmap, cbmptex.GetFullPathname );\r
1445                                                         nLoadDone++;\r
1446                                                         //Trace.TraceInformation( "Main: OnDeviceCreated: " + cbmp.strファイル名 );\r
1447                                                 }\r
1448                                                 else\r
1449                                                 {\r
1450                                                         //Trace.TraceInformation( "Main: Sleeped.");\r
1451                                                         Thread.Sleep( 5 );      // WaitOneのイベント待ちにすると、メインスレッド処理中に2個以上イベント完了したときにそれを正しく検出できなくなるので、\r
1452                                                 }                                               // ポーリングに逃げてしまいました。\r
1453                                         }\r
1454                                         #endregion\r
1455                                 }\r
1456                         }\r
1457                         #endregion\r
1458                         if ( !this.bヘッダのみ )\r
1459                         {\r
1460                                 foreach ( CChip chip in this.listChip )\r
1461                                 {\r
1462                                         #region [ BGAPAN/BGA/BMPTEX/BMP ]\r
1463                                         if ( ( ( ( chip.nチャンネル番号 == 4 ) || ( chip.nチャンネル番号 == 7 ) ) || ( ( chip.nチャンネル番号 >= 0x55 ) && ( chip.nチャンネル番号 <= 0x59 ) ) ) || ( chip.nチャンネル番号 == 0x60 ) )\r
1464                                         {\r
1465                                                 chip.eBGA種別 = EBGA種別.Unknown;\r
1466                                                 chip.rBMP = null;\r
1467                                                 chip.rBMPTEX = null;\r
1468                                                 chip.rBGA = null;\r
1469                                                 chip.rBGAPan = null;\r
1470                                                 #region [ BGAPAN ]\r
1471                                                 if ( this.listBGAPAN.ContainsKey( chip.n整数値 ) )\r
1472                                                 {\r
1473                                                         CBGAPAN cbgapan = this.listBGAPAN[ chip.n整数値 ];\r
1474                                                         if ( this.listBMPTEX.ContainsKey( cbgapan.nBMP番号 ) && this.listBMPTEX[ cbgapan.nBMP番号 ].bUse )\r
1475                                                         {\r
1476                                                                 chip.eBGA種別 = EBGA種別.BGAPAN;\r
1477                                                                 chip.rBMPTEX = this.listBMPTEX[ cbgapan.nBMP番号 ];\r
1478                                                                 chip.rBGAPan = cbgapan;\r
1479                                                                 continue;\r
1480                                                         }\r
1481                                                         if ( this.listBMP.ContainsKey( cbgapan.nBMP番号 ) && this.listBMP[ cbgapan.nBMP番号 ].bUse )\r
1482                                                         {\r
1483                                                                 chip.eBGA種別 = EBGA種別.BGAPAN;\r
1484                                                                 chip.rBMP = this.listBMP[ cbgapan.nBMP番号 ];\r
1485                                                                 chip.rBGAPan = cbgapan;\r
1486                                                                 continue;\r
1487                                                         }\r
1488                                                 }\r
1489                                                 #endregion\r
1490                                                 #region [ BGA ]\r
1491                                                 if ( this.listBGA.ContainsKey( chip.n整数値 ) )\r
1492                                                 {\r
1493                                                         CBGA cbga = this.listBGA[ chip.n整数値 ];\r
1494                                                         if ( this.listBMPTEX.ContainsKey( cbga.nBMP番号 ) && this.listBMPTEX[ cbga.nBMP番号 ].bUse )\r
1495                                                         {\r
1496                                                                 chip.eBGA種別 = EBGA種別.BGA;\r
1497                                                                 chip.rBMPTEX = this.listBMPTEX[ cbga.nBMP番号 ];\r
1498                                                                 chip.rBGA = cbga;\r
1499                                                                 continue;\r
1500                                                         }\r
1501                                                         if ( this.listBMP.ContainsKey( cbga.nBMP番号 ) && this.listBMP[ cbga.nBMP番号 ].bUse )\r
1502                                                         {\r
1503                                                                 chip.eBGA種別 = EBGA種別.BGA;\r
1504                                                                 chip.rBMP = this.listBMP[ cbga.nBMP番号 ];\r
1505                                                                 chip.rBGA = cbga;\r
1506                                                                 continue;\r
1507                                                         }\r
1508                                                 }\r
1509                                                 #endregion\r
1510                                                 #region [ BMPTEX ]\r
1511                                                 if ( this.listBMPTEX.ContainsKey( chip.n整数値 ) && this.listBMPTEX[ chip.n整数値 ].bUse )\r
1512                                                 {\r
1513                                                         chip.eBGA種別 = EBGA種別.BMPTEX;\r
1514                                                         chip.rBMPTEX = this.listBMPTEX[ chip.n整数値 ];\r
1515                                                         continue;\r
1516                                                 }\r
1517                                                 #endregion\r
1518                                                 #region [ BMP ]\r
1519                                                 if ( this.listBMP.ContainsKey( chip.n整数値 ) && this.listBMP[ chip.n整数値 ].bUse )\r
1520                                                 {\r
1521                                                         chip.eBGA種別 = EBGA種別.BMP;\r
1522                                                         chip.rBMP = this.listBMP[ chip.n整数値 ];\r
1523                                                         continue;\r
1524                                                 }\r
1525                                                 #endregion\r
1526                                         }\r
1527                                         #endregion\r
1528                                         #region [ BGA入れ替え ]\r
1529                                         if ( ( ( ( chip.nチャンネル番号 == 0xc4 ) || ( chip.nチャンネル番号 == 0xc7 ) ) || ( ( chip.nチャンネル番号 >= 0xd5 ) && ( chip.nチャンネル番号 <= 0xd9 ) ) ) || ( chip.nチャンネル番号 == 0xe0 ) )\r
1530                                         {\r
1531                                                 chip.eBGA種別 = EBGA種別.Unknown;\r
1532                                                 chip.rBMP = null;\r
1533                                                 chip.rBMPTEX = null;\r
1534                                                 chip.rBGA = null;\r
1535                                                 chip.rBGAPan = null;\r
1536                                                 if ( this.listBMPTEX.ContainsKey( chip.n整数値 ) && this.listBMPTEX[ chip.n整数値 ].bUse )\r
1537                                                 {\r
1538                                                         chip.eBGA種別 = EBGA種別.BMPTEX;\r
1539                                                         chip.rBMPTEX = this.listBMPTEX[ chip.n整数値 ];\r
1540                                                 }\r
1541                                                 else if ( this.listBMP.ContainsKey( chip.n整数値 ) && this.listBMP[ chip.n整数値 ].bUse )\r
1542                                                 {\r
1543                                                         chip.eBGA種別 = EBGA種別.BMP;\r
1544                                                         chip.rBMP = this.listBMP[ chip.n整数値 ];\r
1545                                                 }\r
1546                                         }\r
1547                                         #endregion\r
1548                                 }\r
1549                         }\r
1550                 }\r
1551                 public void tWave再生位置自動補正()\r
1552                 {\r
1553                         foreach( CWAV cwav in this.listWAV.Values )\r
1554                         {\r
1555                                 this.tWave再生位置自動補正( cwav );\r
1556                         }\r
1557                 }\r
1558                 public void tWave再生位置自動補正( CWAV wc )\r
1559                 {\r
1560                         if ( wc.rSound[ 0 ] != null && wc.rSound[ 0 ].n総演奏時間ms >= 5000 )\r
1561                         {\r
1562                                 for ( int i = 0; i < nPolyphonicSounds; i++ )\r
1563                                 {\r
1564                                         if ( ( wc.rSound[ i ] != null ) && ( wc.rSound[ i ].b再生中 ) )\r
1565                                         {\r
1566                                                 long nCurrentTime = CSound管理.rc演奏用タイマ.nシステム時刻ms;\r
1567                                                 if ( nCurrentTime > wc.n再生開始時刻[ i ] )\r
1568                                                 {\r
1569                                                         long nAbsTimeFromStartPlaying = nCurrentTime - wc.n再生開始時刻[ i ];\r
1570                                                         //Trace.TraceInformation( "再生位置自動補正: {0}, seek先={1}ms, 全音長={2}ms",\r
1571                                                         //    Path.GetFileName( wc.rSound[ 0 ].strファイル名 ),\r
1572                                                         //    nAbsTimeFromStartPlaying,\r
1573                                                         //    wc.rSound[ 0 ].n総演奏時間ms\r
1574                                                         //);\r
1575                                                         // wc.rSound[ i ].t再生位置を変更する( wc.rSound[ i ].t時刻から位置を返す( nAbsTimeFromStartPlaying ) );\r
1576                                                         wc.rSound[ i ].t再生位置を変更する( nAbsTimeFromStartPlaying );        // WASAPI/ASIO用\r
1577                                                 }\r
1578                                         }\r
1579                                 }\r
1580                         }\r
1581                 }\r
1582                 public void tWavの再生停止( int nWaveの内部番号 )\r
1583                 {\r
1584                         if( this.listWAV.ContainsKey( nWaveの内部番号 ) )\r
1585                         {\r
1586                                 CWAV cwav = this.listWAV[ nWaveの内部番号 ];\r
1587                                 for ( int i = 0; i < nPolyphonicSounds; i++ )\r
1588                                 {\r
1589                                         if( cwav.rSound[ i ] != null && cwav.rSound[ i ].b再生中 )\r
1590                                         {\r
1591                                                 cwav.rSound[ i ].t再生を停止する();\r
1592                                         }\r
1593                                 }\r
1594                         }\r
1595                 }\r
1596                 public void tWAVの読み込み( CWAV cwav )\r
1597                 {\r
1598 //                      Trace.TraceInformation("WAV files={0}", this.listWAV.Count);\r
1599 //                      int count = 0;\r
1600 //                      foreach (CWAV cwav in this.listWAV.Values)\r
1601                         {\r
1602 //                              string strCount = count.ToString() + " / " + this.listWAV.Count.ToString();\r
1603 //                              Debug.WriteLine(strCount);\r
1604 //                              CDTXMania.act文字コンソール.tPrint(0, 0, C文字コンソール.Eフォント種別.白, strCount);\r
1605 //                              count++;\r
1606 \r
1607                                 string str = string.IsNullOrEmpty(this.PATH_WAV) ? this.strフォルダ名 : this.PATH_WAV;\r
1608                                 str = str + cwav.strファイル名;\r
1609                                 bool bIsDirectSound = ( CDTXMania.Sound管理.GetCurrentSoundDeviceType() == "DirectSound" );\r
1610                                 try\r
1611                                 {\r
1612                                         //try\r
1613                                         //{\r
1614                                         //    cwav.rSound[ 0 ] = CDTXMania.Sound管理.tサウンドを生成する( str );\r
1615                                         //    cwav.rSound[ 0 ].n音量 = 100;\r
1616                                         //    if ( CDTXMania.ConfigIni.bLog作成解放ログ出力 )\r
1617                                         //    {\r
1618                                         //        Trace.TraceInformation( "サウンドを作成しました。({3})({0})({1})({2}bytes)", cwav.strコメント文, str, cwav.rSound[ 0 ].nサウンドバッファサイズ, cwav.rSound[ 0 ].bストリーム再生する ? "Stream" : "OnMemory" );\r
1619                                         //    }\r
1620                                         //}\r
1621                                         //catch\r
1622                                         //{\r
1623                                         //    cwav.rSound[ 0 ] = null;\r
1624                                         //    Trace.TraceError( "サウンドの作成に失敗しました。({0})({1})", cwav.strコメント文, str );\r
1625                                         //}\r
1626                                         //if ( cwav.rSound[ 0 ] == null )       // #xxxxx 2012.5.3 yyagi rSound[1-3]もClone()するようにし、これらのストリーム再生がおかしくなる問題を修正\r
1627                                         //{\r
1628                                         //    for ( int j = 1; j < nPolyphonicSounds; j++ )\r
1629                                         //    {\r
1630                                         //        cwav.rSound[ j ] = null;\r
1631                                         //    }\r
1632                                         //}\r
1633                                         //else\r
1634                                         //{\r
1635                                         //    for ( int j = 1; j < nPolyphonicSounds; j++ )\r
1636                                         //    {\r
1637                                         //        cwav.rSound[ j ] = (CSound) cwav.rSound[ 0 ].Clone(); // #24007 2011.9.5 yyagi add: to accelerate loading chip sounds\r
1638                                         //        CDTXMania.Sound管理.tサウンドを登録する( cwav.rSound[ j ] );\r
1639                                         //    }\r
1640                                         //}\r
1641 \r
1642                                         // まず1つめを登録する\r
1643                                         try\r
1644                                         {\r
1645                                                 cwav.rSound[ 0 ] = CDTXMania.Sound管理.tサウンドを生成する( str );\r
1646                                                 cwav.rSound[ 0 ].n音量 = 100;\r
1647                                                 if ( CDTXMania.ConfigIni.bLog作成解放ログ出力 )\r
1648                                                 {\r
1649                                                         Trace.TraceInformation( "サウンドを作成しました。({3})({0})({1})({2}bytes)", cwav.strコメント文, str, cwav.rSound[ 0 ].nサウンドバッファサイズ, cwav.rSound[ 0 ].bストリーム再生する ? "Stream" : "OnMemory" );\r
1650                                                 }\r
1651                                         }\r
1652                                         catch ( Exception e )\r
1653                                         {\r
1654                                                 cwav.rSound[ 0 ] = null;\r
1655                                                 Trace.TraceError( "サウンドの作成に失敗しました。({0})({1})", cwav.strコメント文, str );\r
1656                                                 Trace.TraceError( "例外: " + e.Message );\r
1657                                         }\r
1658 \r
1659                                         #region [ 同時発音数を、チャンネルによって変える ]\r
1660                                         int nPoly = nPolyphonicSounds;\r
1661                                         if ( CDTXMania.Sound管理.GetCurrentSoundDeviceType() != "DirectSound" )       // DShowでの再生の場合はミキシング負荷が高くないため、\r
1662                                         {                                                                                                                                               // チップのライフタイム管理を行わない\r
1663                                                 if      ( cwav.bIsBassSound )   nPoly = (nPolyphonicSounds >= 2)? 2 : 1;\r
1664                                                 else if ( cwav.bIsGuitarSound ) nPoly = (nPolyphonicSounds >= 2)? 2 : 1;\r
1665                                                 else if ( cwav.bIsSESound )     nPoly = 1;\r
1666                                                 else if ( cwav.bIsBGMSound)     nPoly = 1;\r
1667                                         }\r
1668                                         if ( cwav.bIsBGMSound ) nPoly = 1;\r
1669                                         #endregion\r
1670 \r
1671                                         // 残りはClone等で登録する\r
1672                                         //if ( bIsDirectSound ) // DShowでの再生の場合はCloneする\r
1673                                         //{\r
1674                                         //    for ( int i = 1; i < nPoly; i++ )\r
1675                                         //    {\r
1676                                         //        cwav.rSound[ i ] = (CSound) cwav.rSound[ 0 ].Clone(); // #24007 2011.9.5 yyagi add: to accelerate loading chip sounds\r
1677                                         //        // CDTXMania.Sound管理.tサウンドを登録する( cwav.rSound[ j ] );\r
1678                                         //    }\r
1679                                         //    for ( int i = nPoly; i < nPolyphonicSounds; i++ )\r
1680                                         //    {\r
1681                                         //        cwav.rSound[ i ] = null;\r
1682                                         //    }\r
1683                                         //}\r
1684                                         //else                                                                                                                  // WASAPI/ASIO時は通常通り登録\r
1685                                         {\r
1686                                                 for ( int i = 1; i < nPoly; i++ )\r
1687                                                 {\r
1688                                                         try\r
1689                                                         {\r
1690                                                                 cwav.rSound[ i ] = CDTXMania.Sound管理.tサウンドを生成する( str );\r
1691                                                                 cwav.rSound[ i ].n音量 = 100;\r
1692                                                                 if ( CDTXMania.ConfigIni.bLog作成解放ログ出力 )\r
1693                                                                 {\r
1694                                                                         Trace.TraceInformation( "サウンドを作成しました。({3})({0})({1})({2}bytes)", cwav.strコメント文, str, cwav.rSound[ 0 ].nサウンドバッファサイズ, cwav.rSound[ 0 ].bストリーム再生する ? "Stream" : "OnMemory" );\r
1695                                                                 }\r
1696                                                         }\r
1697                                                         catch ( Exception e )\r
1698                                                         {\r
1699                                                                 cwav.rSound[ i ] = null;\r
1700                                                                 Trace.TraceError( "サウンドの作成に失敗しました。({0})({1})", cwav.strコメント文, str );\r
1701                                                                 Trace.TraceError( "例外: " + e.Message );\r
1702                                                         }\r
1703                                                 }\r
1704                                         }\r
1705                                 }\r
1706                                 catch( Exception exception )\r
1707                                 {\r
1708                                         Trace.TraceError( "サウンドの生成に失敗しました。({0})({1})({2})", exception.Message, cwav.strコメント文, str );\r
1709                                         for ( int j = 0; j < nPolyphonicSounds; j++ )\r
1710                                         {\r
1711                                                 cwav.rSound[ j ] = null;\r
1712                                         }\r
1713                                         //continue;\r
1714                                 }\r
1715                         }\r
1716                 }\r
1717                 public static string tZZ( int n )\r
1718                 {\r
1719                         if( n < 0 || n >= 36 * 36 )\r
1720                                 return "!!";    // オーバー/アンダーフロー。\r
1721 \r
1722                         // n を36進数2桁の文字列にして返す。\r
1723 \r
1724                         string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";\r
1725                         return new string( new char[] { str[ n / 36 ], str[ n % 36 ] } );\r
1726                 }\r
1727                 public void tギターとベースのランダム化(E楽器パート part, Eランダムモード eRandom)\r
1728                 {\r
1729                         if( ( ( part == E楽器パート.GUITAR ) || ( part == E楽器パート.BASS ) ) && ( eRandom != Eランダムモード.OFF ) )\r
1730                         {\r
1731                                 int[,] nランダムレーン候補 = new int[ , ] { { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 2, 1, 3, 4, 6, 5, 7 }, { 0, 1, 4, 5, 2, 3, 6, 7 }, { 0, 2, 4, 6, 1, 3, 5, 7 }, { 0, 4, 1, 5, 2, 6, 3, 7 }, { 0, 4, 2, 6, 1, 5, 3, 7 } };\r
1732                                 int n小節番号 = -10000;\r
1733                                 int n小節内乱数6通り = 0;\r
1734                                 // int GOTO_END = 0;    // gotoの飛び先のダミーコードで使うダミー変数\r
1735                                 foreach( CChip chip in this.listChip )\r
1736                                 {\r
1737                                         int nRGBレーンビットパターン;\r
1738                                         int n新RGBレーンビットパターン = 0;                          // 「未割り当てのローカル変数」ビルドエラー回避のために0を初期値に設定\r
1739                                         bool flag;\r
1740                                         if( ( chip.n発声位置 / 384 ) != n小節番号 )             // 小節が変化したら\r
1741                                         {\r
1742                                                 n小節番号 = chip.n発声位置 / 384;\r
1743                                                 n小節内乱数6通り = CDTXMania.Random.Next( 6 );\r
1744                                         }\r
1745                                         int nランダム化前チャンネル番号 = chip.nチャンネル番号;\r
1746                                         if(             ( ( ( part != E楽器パート.GUITAR ) || ( 0x20 > nランダム化前チャンネル番号 ) ) || ( nランダム化前チャンネル番号 > 0x27 ) )\r
1747                                                 &&      ( ( ( part != E楽器パート.BASS )   || ( 0xA0 > nランダム化前チャンネル番号 ) ) || ( nランダム化前チャンネル番号 > 0xa7 ) )\r
1748                                         )\r
1749                                         {\r
1750                                                 continue;\r
1751                                         }\r
1752                                         switch( eRandom )\r
1753                                         {\r
1754                                                 case Eランダムモード.RANDOM:             // 1小節単位でレーンのR/G/Bがランダムに入れ替わる\r
1755                                                         chip.nチャンネル番号 = ( nランダム化前チャンネル番号 & 0xF0 ) | nランダムレーン候補[ n小節内乱数6通り, nランダム化前チャンネル番号 & 0x07 ];\r
1756                                                         continue;       // goto Label_02C4;\r
1757 \r
1758                                                 case Eランダムモード.SUPERRANDOM:        // チップごとにR/G/Bがランダムで入れ替わる(レーンの本数までは変わらない)。\r
1759                                                         chip.nチャンネル番号 = ( nランダム化前チャンネル番号 & 0xF0 ) | nランダムレーン候補[ CDTXMania.Random.Next( 6 ), nランダム化前チャンネル番号 & 0x07 ];\r
1760                                                         continue;       // goto Label_02C4;\r
1761 \r
1762                                                 case Eランダムモード.HYPERRANDOM:        // レーンの本数も変わる\r
1763                                                         nRGBレーンビットパターン = nランダム化前チャンネル番号 & 7;\r
1764                                                         // n新RGBレーンビットパターン = (int)Eレーンビットパターン.OPEN;   // この値は結局未使用なので削除\r
1765                                                         flag = ((part == E楽器パート.GUITAR) && this.bチップがある.OpenGuitar) || ((part == E楽器パート.BASS) && this.bチップがある.OpenBass);    // #23546 2010.10.28 yyagi fixed (bチップがある.Bass→bチップがある.OpenBass)\r
1766                                                         if (((nRGBレーンビットパターン != (int)Eレーンビットパターン.xxB) && (nRGBレーンビットパターン != (int)Eレーンビットパターン.xGx)) && (nRGBレーンビットパターン != (int)Eレーンビットパターン.Rxx))         // xxB, xGx, Rxx レーン1本相当\r
1767                                                         {\r
1768                                                                 break;                                                                                                                  // レーン1本相当でなければ、とりあえず先に進む\r
1769                                                         }\r
1770                                                         n新RGBレーンビットパターン = CDTXMania.Random.Next( 6 ) + 1;         // レーン1本相当なら、レーン1本か2本(1~6)に変化して終了\r
1771                                                         goto Label_02B2;\r
1772 \r
1773                                                 default:\r
1774                                                         continue;       // goto Label_02C4;\r
1775                                         }\r
1776                                         switch( nRGBレーンビットパターン )\r
1777                                         {\r
1778                                                 case (int)Eレーンビットパターン.xGB:  // xGB  レーン2本相当\r
1779                                                 case (int)Eレーンビットパターン.RxB:  // RxB\r
1780                                                 case (int)Eレーンビットパターン.RGx:  // RGx\r
1781                                                         n新RGBレーンビットパターン = flag ? CDTXMania.Random.Next( 8 ) : ( CDTXMania.Random.Next( 7 ) + 1 ); // OPENあり譜面ならOPENを含むランダム, OPENなし譜面ならOPENを含まないランダム\r
1782                                                         break;  // goto Label_02B2;\r
1783 \r
1784                                                 default:\r
1785                                                         if( nRGBレーンビットパターン == (int)Eレーンビットパターン.RGB )    // RGB レーン3本相当\r
1786                                                         {\r
1787                                                                 if( flag )      // OPENあり譜面の場合\r
1788                                                                 {\r
1789                                                                         int n乱数パーセント = CDTXMania.Random.Next( 100 );\r
1790                                                                         if( n乱数パーセント < 30 )\r
1791                                                                         {\r
1792                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.OPEN;\r
1793                                                                         }\r
1794                                                                         else if( n乱数パーセント < 60 )\r
1795                                                                         {\r
1796                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.RGB;\r
1797                                                                         }\r
1798                                                                         else if( n乱数パーセント < 85 )\r
1799                                                                         {\r
1800                                                                                 switch( CDTXMania.Random.Next( 3 ) )\r
1801                                                                                 {\r
1802                                                                                         case 0:\r
1803                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.xGB;\r
1804                                                                                                 break;  // goto Label_02B2;\r
1805 \r
1806                                                                                         case 1:\r
1807                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.RxB;\r
1808                                                                                                 break;  // goto Label_02B2;\r
1809                                                                                 }\r
1810                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.RGx;\r
1811                                                                         }\r
1812                                                                         else    // OPENでない場合\r
1813                                                                         {\r
1814                                                                                 switch( CDTXMania.Random.Next( 3 ) )\r
1815                                                                                 {\r
1816                                                                                         case 0:\r
1817                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.xxB;\r
1818                                                                                                 break;  // goto Label_02B2;\r
1819 \r
1820                                                                                         case 1:\r
1821                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.xGx;\r
1822                                                                                                 break;  // goto Label_02B2;\r
1823                                                                                 }\r
1824                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.Rxx;\r
1825                                                                         }\r
1826                                                                 }\r
1827                                                                 else    // OPENなし譜面の場合\r
1828                                                                 {\r
1829                                                                         int n乱数パーセント = CDTXMania.Random.Next( 100 );\r
1830                                                                         if( n乱数パーセント < 60 )\r
1831                                                                         {\r
1832                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.RGB;\r
1833                                                                         }\r
1834                                                                         else if( n乱数パーセント < 85 )\r
1835                                                                         {\r
1836                                                                                 switch( CDTXMania.Random.Next( 3 ) )\r
1837                                                                                 {\r
1838                                                                                         case 0:\r
1839                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.xGB;\r
1840                                                                                                 break;  // goto Label_02B2;\r
1841 \r
1842                                                                                         case 1:\r
1843                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.RxB;\r
1844                                                                                                 break;  // goto Label_02B2;\r
1845                                                                                 }\r
1846                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.RGx;\r
1847                                                                         }\r
1848                                                                         else\r
1849                                                                         {\r
1850                                                                                 switch( CDTXMania.Random.Next( 3 ) )\r
1851                                                                                 {\r
1852                                                                                         case 0:\r
1853                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.xxB;\r
1854                                                                                                 break;  // goto Label_02B2;\r
1855 \r
1856                                                                                         case 1:\r
1857                                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.xGx;\r
1858                                                                                                 break;  // goto Label_02B2;\r
1859                                                                                 }\r
1860                                                                                 n新RGBレーンビットパターン = (int)Eレーンビットパターン.Rxx;\r
1861                                                                         }\r
1862                                                                 }\r
1863                                                         }\r
1864                                                         break;  // goto Label_02B2;\r
1865                                         }\r
1866                                 Label_02B2:\r
1867                                         chip.nチャンネル番号 = ( nランダム化前チャンネル番号 & 0xF0 ) | n新RGBレーンビットパターン;\r
1868 //                              Label_02C4:\r
1869 //                                      GOTO_END++;             // goto用のダミーコード\r
1870                                 }\r
1871                         }\r
1872                 }\r
1873 \r
1874                 #region [ チップの再生と停止 ]\r
1875                 public void tチップの再生( CChip rChip, long n再生開始システム時刻ms, int nLane )\r
1876                 {\r
1877                         this.tチップの再生( rChip, n再生開始システム時刻ms, nLane, CDTXMania.ConfigIni.n自動再生音量, false, false );\r
1878                 }\r
1879                 public void tチップの再生( CChip rChip, long n再生開始システム時刻ms, int nLane, int nVol )\r
1880                 {\r
1881                         this.tチップの再生( rChip, n再生開始システム時刻ms, nLane, nVol, false, false );\r
1882                 }\r
1883                 public void tチップの再生( CChip rChip, long n再生開始システム時刻ms, int nLane, int nVol, bool bMIDIMonitor )\r
1884                 {\r
1885                         this.tチップの再生( rChip, n再生開始システム時刻ms, nLane, nVol, bMIDIMonitor, false );\r
1886                 }\r
1887                 public void tチップの再生( CChip pChip, long n再生開始システム時刻ms, int nLane, int nVol, bool bMIDIMonitor, bool bBad )\r
1888                 {\r
1889                         if( pChip.n整数値・内部番号 >= 0 )\r
1890                         {\r
1891                                 if( ( nLane < (int) Eレーン.LC ) || ( (int) Eレーン.BGM < nLane ) )\r
1892                                 {\r
1893                                         throw new ArgumentOutOfRangeException();\r
1894                                 }\r
1895                                 if( this.listWAV.ContainsKey( pChip.n整数値・内部番号 ) )\r
1896                                 {\r
1897                                         CWAV wc = this.listWAV[ pChip.n整数値・内部番号 ];\r
1898                                         int index = wc.n現在再生中のサウンド番号 = ( wc.n現在再生中のサウンド番号 + 1 ) % nPolyphonicSounds;\r
1899                                         if( ( wc.rSound[ 0 ] != null ) && \r
1900                                                 ( wc.rSound[ 0 ].bストリーム再生する || wc.rSound[index] == null ) )\r
1901                                         {\r
1902                                                 index = wc.n現在再生中のサウンド番号 = 0;\r
1903                                         }\r
1904                                         CSound sound = wc.rSound[ index ];\r
1905                                         if( sound != null )\r
1906                                         {\r
1907                                                 if( bBad )\r
1908                                                 {\r
1909                                                         sound.db周波数倍率 = ( (float) ( 100 + ( ( ( CDTXMania.Random.Next( 3 ) + 1 ) * 7 ) * ( 1 - ( CDTXMania.Random.Next( 2 ) * 2 ) ) ) ) ) / 100f;\r
1910                                                 }\r
1911                                                 else\r
1912                                                 {\r
1913                                                         sound.db周波数倍率 = 1.0;\r
1914                                                 }\r
1915                                                 sound.db再生速度 = ( (double) CDTXMania.ConfigIni.n演奏速度 ) / 20.0;\r
1916                                                 // 再生速度によって、WASAPI/ASIOで使う使用mixerが決まるため、付随情報の設定(音量/PAN)は、再生速度の設定後に行う\r
1917                                                 sound.n音量 = (int) ( ( (double) ( nVol * wc.n音量 ) ) / 100.0 );\r
1918                                                 sound.n位置 = wc.n位置;\r
1919                                                 sound.t再生を開始する();\r
1920                                         }\r
1921                                         wc.n再生開始時刻[ wc.n現在再生中のサウンド番号 ] = n再生開始システム時刻ms;\r
1922                                         this.tWave再生位置自動補正( wc );\r
1923                                 }\r
1924                         }\r
1925                 }\r
1926                 public void t各自動再生音チップの再生時刻を変更する( int nBGMAdjustの増減値 )\r
1927                 {\r
1928                         this.nBGMAdjust += nBGMAdjustの増減値;\r
1929                         for( int i = 0; i < this.listChip.Count; i++ )\r
1930                         {\r
1931                                 int nChannelNumber = this.listChip[ i ].nチャンネル番号;\r
1932                                 if( ( (\r
1933                                                 ( nChannelNumber == 1 ) ||\r
1934                                                 ( ( 0x61 <= nChannelNumber ) && ( nChannelNumber <= 0x69 ) )\r
1935                                           ) ||\r
1936                                                 ( ( 0x70 <= nChannelNumber ) && ( nChannelNumber <= 0x79 ) )\r
1937                                         ) ||\r
1938                                         ( ( ( 0x80 <= nChannelNumber ) && ( nChannelNumber <= 0x89 ) ) || ( ( 0x90 <= nChannelNumber ) && ( nChannelNumber <= 0x92 ) ) )\r
1939                                   )\r
1940                                 {\r
1941                                         this.listChip[ i ].n発声時刻ms += nBGMAdjustの増減値;\r
1942                                 }\r
1943                         }\r
1944                         foreach( CWAV cwav in this.listWAV.Values )\r
1945                         {\r
1946                                 for ( int j = 0; j < nPolyphonicSounds; j++ )\r
1947                                 {\r
1948                                         if( ( cwav.rSound[ j ] != null ) && cwav.rSound[ j ].b再生中 )\r
1949                                         {\r
1950                                                 cwav.n再生開始時刻[ j ] += nBGMAdjustの増減値;\r
1951                                         }\r
1952                                 }\r
1953                         }\r
1954                 }\r
1955                 public void t全チップの再生一時停止()\r
1956                 {\r
1957                         foreach( CWAV cwav in this.listWAV.Values )\r
1958                         {\r
1959                                 for ( int i = 0; i < nPolyphonicSounds; i++ )\r
1960                                 {\r
1961                                         if( ( cwav.rSound[ i ] != null ) && cwav.rSound[ i ].b再生中 )\r
1962                                         {\r
1963                                                 cwav.rSound[ i ].t再生を一時停止する();\r
1964                                                 cwav.n一時停止時刻[ i ] = CSound管理.rc演奏用タイマ.nシステム時刻ms;\r
1965                                         }\r
1966                                 }\r
1967                         }\r
1968                 }\r
1969                 public void t全チップの再生再開()\r
1970                 {\r
1971                         foreach( CWAV cwav in this.listWAV.Values )\r
1972                         {\r
1973                                 for ( int i = 0; i < nPolyphonicSounds; i++ )\r
1974                                 {\r
1975                                         if( ( cwav.rSound[ i ] != null ) && cwav.rSound[ i ].b一時停止中 )\r
1976                                         {\r
1977                                                 //long num1 = cwav.n一時停止時刻[ i ];\r
1978                                                 //long num2 = cwav.n再生開始時刻[ i ];\r
1979                                                 cwav.rSound[ i ].t再生を再開する( cwav.n一時停止時刻[ i ] - cwav.n再生開始時刻[ i ] );\r
1980                                                 cwav.n再生開始時刻[ i ] += CSound管理.rc演奏用タイマ.nシステム時刻ms - cwav.n一時停止時刻[ i ];\r
1981                                         }\r
1982                                 }\r
1983                         }\r
1984                 }\r
1985                 public void t全チップの再生停止()\r
1986                 {\r
1987                         foreach( CWAV cwav in this.listWAV.Values )\r
1988                         {\r
1989                                 this.tWavの再生停止( cwav.n内部番号 );\r
1990                         }\r
1991                 }\r
1992                 #endregion\r
1993 \r
1994                 public void t入力( string strファイル名, bool bヘッダのみ )\r
1995                 {\r
1996                         this.t入力( strファイル名, bヘッダのみ, 1.0, 0 );\r
1997                 }\r
1998                 public void t入力( string strファイル名, bool bヘッダのみ, double db再生速度, int nBGMAdjust )\r
1999                 {\r
2000                         this.bヘッダのみ = bヘッダのみ;\r
2001                         this.strファイル名の絶対パス = Path.GetFullPath( strファイル名 );\r
2002                         this.strファイル名 = Path.GetFileName( this.strファイル名の絶対パス );\r
2003                         this.strフォルダ名 = Path.GetDirectoryName( this.strファイル名の絶対パス ) + @"\";\r
2004                         string ext = Path.GetExtension( this.strファイル名 ).ToLower();\r
2005                         if ( ext != null )\r
2006                         {\r
2007                                 if ( !( ext == ".dtx" ) )\r
2008                                 {\r
2009                                         if ( ext == ".gda" )\r
2010                                         {\r
2011                                                 this.e種別 = E種別.GDA;\r
2012                                         }\r
2013                                         else if ( ext == ".g2d" )\r
2014                                         {\r
2015                                                 this.e種別 = E種別.G2D;\r
2016                                         }\r
2017                                         else if ( ext == ".bms" )\r
2018                                         {\r
2019                                                 this.e種別 = E種別.BMS;\r
2020                                         }\r
2021                                         else if ( ext == ".bme" )\r
2022                                         {\r
2023                                                 this.e種別 = E種別.BME;\r
2024                                         }\r
2025                                         else if ( ext == ".mid" )\r
2026                                         {\r
2027                                                 this.e種別 = E種別.SMF;\r
2028                                         }\r
2029                                 }\r
2030                                 else\r
2031                                 {\r
2032                                         this.e種別 = E種別.DTX;\r
2033                                 }\r
2034                         }\r
2035                         if ( this.e種別 != E種別.SMF )\r
2036                         {\r
2037                                 try\r
2038                                 {\r
2039                                         //DateTime timeBeginLoad = DateTime.Now;\r
2040                                         //TimeSpan span;\r
2041 \r
2042                                         StreamReader reader = new StreamReader( strファイル名, Encoding.GetEncoding( "Shift_JIS" ) );\r
2043                                         string str2 = reader.ReadToEnd();\r
2044                                         reader.Close();\r
2045                                         //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2046                                         //Trace.TraceInformation( "DTXfileload時間:          {0}", span.ToString() );\r
2047 \r
2048                                         this.t入力・全入力文字列から( str2, db再生速度, nBGMAdjust );\r
2049                                 }\r
2050                                 catch\r
2051                                 {\r
2052                                 }\r
2053                         }\r
2054                         else\r
2055                         {\r
2056                                 Trace.TraceWarning( "SMF の演奏は未対応です。(検討中)" );\r
2057                         }\r
2058                 }\r
2059                 public void t入力・全入力文字列から( string str全入力文字列 )\r
2060                 {\r
2061                         this.t入力・全入力文字列から( str全入力文字列, 1.0, 0 );\r
2062                 }\r
2063                 public unsafe void t入力・全入力文字列から( string str全入力文字列, double db再生速度, int nBGMAdjust )\r
2064                 {\r
2065                         //DateTime timeBeginLoad = DateTime.Now;\r
2066                         //TimeSpan span;\r
2067 \r
2068                         if ( !string.IsNullOrEmpty( str全入力文字列 ) )\r
2069                         {\r
2070                                 #region [ 改行カット ]\r
2071                                 this.db再生速度 = db再生速度;\r
2072                                 str全入力文字列 = str全入力文字列.Replace( Environment.NewLine, "\n" );\r
2073                                 str全入力文字列 = str全入力文字列.Replace( '\t', ' ' );\r
2074                                 str全入力文字列 = str全入力文字列 + "\n";\r
2075                                 #endregion\r
2076                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2077                                 //Trace.TraceInformation( "改行カット時間:           {0}", span.ToString() );\r
2078                                 //timeBeginLoad = DateTime.Now;\r
2079                                 #region [ 初期化 ]\r
2080                                 for ( int j = 0; j < 36 * 36; j++ )\r
2081                                 {\r
2082                                         this.n無限管理WAV[ j ] = -j;\r
2083                                         this.n無限管理BPM[ j ] = -j;\r
2084                                         this.n無限管理VOL[ j ] = -j;\r
2085                                         this.n無限管理PAN[ j ] = -10000 - j;\r
2086                                         this.n無限管理SIZE[ j ] = -j;\r
2087                                 }\r
2088                                 this.n内部番号WAV1to = 1;\r
2089                                 this.n内部番号BPM1to = 1;\r
2090                                 this.bstackIFからENDIFをスキップする = new Stack<bool>();\r
2091                                 this.bstackIFからENDIFをスキップする.Push( false );\r
2092                                 this.n現在の乱数 = 0;\r
2093                                 for ( int k = 0; k < 7; k++ )\r
2094                                 {\r
2095                                         this.nRESULTIMAGE用優先順位[ k ] = 0;\r
2096                                         this.nRESULTMOVIE用優先順位[ k ] = 0;\r
2097                                         this.nRESULTSOUND用優先順位[ k ] = 0;\r
2098                                 }\r
2099                                 #endregion\r
2100                                 #region [ 入力/行解析 ]\r
2101                                 CharEnumerator ce = str全入力文字列.GetEnumerator();\r
2102                                 if ( ce.MoveNext() )\r
2103                                 {\r
2104                                         this.n現在の行数 = 1;\r
2105                                         do\r
2106                                         {\r
2107                                                 if ( !this.t入力・空白と改行をスキップする( ref ce ) )\r
2108                                                 {\r
2109                                                         break;\r
2110                                                 }\r
2111                                                 if ( ce.Current == '#' )\r
2112                                                 {\r
2113                                                         if ( ce.MoveNext() )\r
2114                                                         {\r
2115                                                                 StringBuilder builder = new StringBuilder( 0x20 );\r
2116                                                                 if ( this.t入力・コマンド文字列を抜き出す( ref ce, ref builder ) )\r
2117                                                                 {\r
2118                                                                         StringBuilder builder2 = new StringBuilder( 0x400 );\r
2119                                                                         if ( this.t入力・パラメータ文字列を抜き出す( ref ce, ref builder2 ) )\r
2120                                                                         {\r
2121                                                                                 StringBuilder builder3 = new StringBuilder( 0x400 );\r
2122                                                                                 if ( this.t入力・コメント文字列を抜き出す( ref ce, ref builder3 ) )\r
2123                                                                                 {\r
2124                                                                                         this.t入力・行解析( ref builder, ref builder2, ref builder3 );\r
2125                                                                                         this.n現在の行数++;\r
2126                                                                                         continue;\r
2127                                                                                 }\r
2128                                                                         }\r
2129                                                                 }\r
2130                                                         }\r
2131                                                         break;\r
2132                                                 }\r
2133                                         }\r
2134                                         while ( this.t入力・コメントをスキップする( ref ce ) );\r
2135                                 #endregion\r
2136                                         //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2137                                         //Trace.TraceInformation( "抜き出し時間:             {0}", span.ToString() );\r
2138                                         //timeBeginLoad = DateTime.Now;\r
2139                                         this.n無限管理WAV = null;\r
2140                                         this.n無限管理BPM = null;\r
2141                                         this.n無限管理VOL = null;\r
2142                                         this.n無限管理PAN = null;\r
2143                                         this.n無限管理SIZE = null;\r
2144                                         if ( !this.bヘッダのみ )\r
2145                                         {\r
2146                                                 #region [ BPM/BMP初期化 ]\r
2147                                                 int ch;\r
2148                                                 CBPM cbpm = null;\r
2149                                                 foreach ( CBPM cbpm2 in this.listBPM.Values )\r
2150                                                 {\r
2151                                                         if ( cbpm2.n表記上の番号 == 0 )\r
2152                                                         {\r
2153                                                                 cbpm = cbpm2;\r
2154                                                                 break;\r
2155                                                         }\r
2156                                                 }\r
2157                                                 if ( cbpm == null )\r
2158                                                 {\r
2159                                                         cbpm = new CBPM();\r
2160                                                         cbpm.n内部番号 = this.n内部番号BPM1to++;\r
2161                                                         cbpm.n表記上の番号 = 0;\r
2162                                                         cbpm.dbBPM値 = 120.0;\r
2163                                                         this.listBPM.Add( cbpm.n内部番号, cbpm );\r
2164                                                         CChip chip = new CChip();\r
2165                                                         chip.n発声位置 = 0;\r
2166                                                         chip.nチャンネル番号 = 8;                // 拡張BPM\r
2167                                                         chip.n整数値 = 0;\r
2168                                                         chip.n整数値・内部番号 = cbpm.n内部番号;\r
2169                                                         this.listChip.Insert( 0, chip );\r
2170                                                 }\r
2171                                                 else\r
2172                                                 {\r
2173                                                         CChip chip = new CChip();\r
2174                                                         chip.n発声位置 = 0;\r
2175                                                         chip.nチャンネル番号 = 8;                // 拡張BPM\r
2176                                                         chip.n整数値 = 0;\r
2177                                                         chip.n整数値・内部番号 = cbpm.n内部番号;\r
2178                                                         this.listChip.Insert( 0, chip );\r
2179                                                 }\r
2180                                                 if ( this.listBMP.ContainsKey( 0 ) )\r
2181                                                 {\r
2182                                                         CChip chip = new CChip();\r
2183                                                         chip.n発声位置 = 0;\r
2184                                                         chip.nチャンネル番号 = 4;                // BGA (レイヤBGA1)\r
2185                                                         chip.n整数値 = 0;\r
2186                                                         chip.n整数値・内部番号 = 0;\r
2187                                                         this.listChip.Insert( 0, chip );\r
2188                                                 }\r
2189                                                 #endregion\r
2190                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2191                                                 //Trace.TraceInformation( "前準備完了時間:           {0}", span.ToString() );\r
2192                                                 //timeBeginLoad = DateTime.Now;\r
2193                                                 #region [ CWAV初期化 ]\r
2194                                                 foreach ( CWAV cwav in this.listWAV.Values )\r
2195                                                 {\r
2196                                                         if ( cwav.nチップサイズ < 0 )\r
2197                                                         {\r
2198                                                                 cwav.nチップサイズ = 100;\r
2199                                                         }\r
2200                                                         if ( cwav.n位置 <= -10000 )\r
2201                                                         {\r
2202                                                                 cwav.n位置 = 0;\r
2203                                                         }\r
2204                                                         if ( cwav.n音量 < 0 )\r
2205                                                         {\r
2206                                                                 cwav.n音量 = 100;\r
2207                                                         }\r
2208                                                 }\r
2209                                                 #endregion\r
2210                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2211                                                 //Trace.TraceInformation( "CWAV前準備時間:           {0}", span.ToString() );\r
2212                                                 //timeBeginLoad = DateTime.Now;\r
2213                                                 #region [ チップ倍率設定 ]                                               // #28145 2012.4.22 yyagi 二重ループを1重ループに変更して高速化)\r
2214                                                 //foreach ( CWAV cwav in this.listWAV.Values )\r
2215                                                 //{\r
2216                                                 //    foreach( CChip chip in this.listChip )\r
2217                                                 //    {\r
2218                                                 //        if( chip.n整数値・内部番号 == cwav.n内部番号 )\r
2219                                                 //        {\r
2220                                                 //            chip.dbチップサイズ倍率 = ( (double) cwav.nチップサイズ ) / 100.0;\r
2221                                                 //            if (chip.nチャンネル番号 == 0x01 ) // BGMだったら\r
2222                                                 //            {\r
2223                                                 //                cwav.bIsOnBGMLane = true;\r
2224                                                 //            }\r
2225                                                 //        }\r
2226                                                 //    }\r
2227                                                 //}\r
2228                                                 foreach ( CChip chip in this.listChip )\r
2229                                                 {\r
2230                                                         if ( this.listWAV.ContainsKey( chip.n整数値・内部番号 ) )\r
2231                                                         //foreach ( CWAV cwav in this.listWAV.Values )\r
2232                                                         {\r
2233                                                                 CWAV cwav = this.listWAV[ chip.n整数値・内部番号 ];\r
2234                                                                 //      if ( chip.n整数値・内部番号 == cwav.n内部番号 )\r
2235                                                                 //      {\r
2236                                                                 chip.dbチップサイズ倍率 = ( (double) cwav.nチップサイズ ) / 100.0;\r
2237                                                                 //if ( chip.nチャンネル番号 == 0x01 )    // BGMだったら\r
2238                                                                 //{\r
2239                                                                 //      cwav.bIsOnBGMLane = true;\r
2240                                                                 //}\r
2241                                                                 //      }\r
2242                                                         }\r
2243                                                 }\r
2244                                                 #endregion\r
2245                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2246                                                 //Trace.TraceInformation( "CWAV全準備時間:           {0}", span.ToString() );\r
2247                                                 //timeBeginLoad = DateTime.Now;\r
2248                                                 #region [ 必要に応じて空打ち音を0小節に定義する ]\r
2249                                                 //for ( int m = 0xb1; m <= 0xbc; m++ )                  // #28146 2012.4.21 yyagi; bb -> bc\r
2250                                                 //{\r
2251                                                 //    foreach ( CChip chip in this.listChip )\r
2252                                                 //    {\r
2253                                                 //        if ( chip.nチャンネル番号 == m )\r
2254                                                 //        {\r
2255                                                 //            CChip c = new CChip();\r
2256                                                 //            c.n発声位置 = 0;\r
2257                                                 //            c.nチャンネル番号 = chip.nチャンネル番号;\r
2258                                                 //            c.n整数値 = chip.n整数値;\r
2259                                                 //            c.n整数値・内部番号 = chip.n整数値・内部番号;\r
2260                                                 //            this.listChip.Insert( 0, c );\r
2261                                                 //            break;\r
2262                                                 //        }\r
2263                                                 //    }\r
2264                                                 //}\r
2265                                                 #endregion\r
2266                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2267                                                 //Trace.TraceInformation( "空打確認時間:             {0}", span.ToString() );\r
2268                                                 //timeBeginLoad = DateTime.Now;\r
2269                                                 #region [ 拍子・拍線の挿入 ]\r
2270                                                 if ( this.listChip.Count > 0 )\r
2271                                                 {\r
2272                                                         this.listChip.Sort();           // 高速化のためにはこれを削りたいが、listChipの最後がn発声位置の終端である必要があるので、\r
2273                                                         // 保守性確保を優先してここでのソートは残しておく\r
2274                                                         // なお、093時点では、このソートを削除しても動作するようにはしてある。\r
2275                                                         // (ここまでの一部チップ登録を、listChip.Add(c)から同Insert(0,c)に変更してある)\r
2276                                                         // これにより、数ms程度ながらここでのソートも高速化されている。\r
2277                                                         double barlength = 1.0;\r
2278                                                         int nEndOfSong = ( this.listChip[ this.listChip.Count - 1 ].n発声位置 + 384 ) - ( this.listChip[ this.listChip.Count - 1 ].n発声位置 % 384 );\r
2279                                                         for ( int tick384 = 0; tick384 <= nEndOfSong; tick384 += 384 )  // 小節線の挿入 (後に出てくる拍子線とループをまとめようとするなら、forループの終了条件の微妙な違いに注意が必要)\r
2280                                                         {\r
2281                                                                 CChip chip = new CChip();\r
2282                                                                 chip.n発声位置 = tick384;\r
2283                                                                 chip.nチャンネル番号 = 0x50;     // 小節線\r
2284                                                                 chip.n整数値 = 36 * 36 - 1;\r
2285                                                                 this.listChip.Add( chip );\r
2286                                                         }\r
2287                                                         //this.listChip.Sort();                         // ここでのソートは不要。ただし最後にソートすること\r
2288                                                         int nChipNo_BarLength = 0;\r
2289                                                         int nChipNo_C1 = 0;\r
2290                                                         for ( int tick384 = 0; tick384 < nEndOfSong; tick384 += 384 )\r
2291                                                         {\r
2292                                                                 int n発声位置_C1_同一小節内 = 0;\r
2293                                                                 while ( ( nChipNo_C1 < this.listChip.Count ) && ( this.listChip[ nChipNo_C1 ].n発声位置 < ( tick384 + 384 ) ) )\r
2294                                                                 {\r
2295                                                                         if ( this.listChip[ nChipNo_C1 ].nチャンネル番号 == 0xc1 )                               // 拍線シフトの検出\r
2296                                                                         {\r
2297                                                                                 n発声位置_C1_同一小節内 = this.listChip[ nChipNo_C1 ].n発声位置 - tick384;\r
2298                                                                         }\r
2299                                                                         nChipNo_C1++;\r
2300                                                                 }\r
2301                                                                 if ( ( this.e種別 == E種別.BMS ) || ( this.e種別 == E種別.BME ) )\r
2302                                                                 {\r
2303                                                                         barlength = 1.0;\r
2304                                                                 }\r
2305                                                                 while ( ( nChipNo_BarLength < this.listChip.Count ) && ( this.listChip[ nChipNo_BarLength ].n発声位置 <= tick384 ) )\r
2306                                                                 {\r
2307                                                                         if ( this.listChip[ nChipNo_BarLength ].nチャンネル番号 == 0x02 )                // bar lengthの検出\r
2308                                                                         {\r
2309                                                                                 barlength = this.listChip[ nChipNo_BarLength ].db実数値;\r
2310                                                                         }\r
2311                                                                         nChipNo_BarLength++;\r
2312                                                                 }\r
2313                                                                 for ( int i = 0; i < 100; i++ )                                                         // 拍線の挿入\r
2314                                                                 {\r
2315                                                                         int tickBeat = (int) ( ( (double) ( 384 * i ) ) / ( 4.0 * barlength ) );\r
2316                                                                         if ( ( tickBeat + n発声位置_C1_同一小節内 ) >= 384 )\r
2317                                                                         {\r
2318                                                                                 break;\r
2319                                                                         }\r
2320                                                                         if ( ( ( tickBeat + n発声位置_C1_同一小節内 ) % 384 ) != 0 )\r
2321                                                                         {\r
2322                                                                                 CChip chip = new CChip();\r
2323                                                                                 chip.n発声位置 = tick384 + ( tickBeat + n発声位置_C1_同一小節内 );\r
2324                                                                                 chip.nチャンネル番号 = 0x51;                                             // beat line 拍線\r
2325                                                                                 chip.n整数値 = 36 * 36 - 1;\r
2326                                                                                 this.listChip.Add( chip );\r
2327                                                                         }\r
2328                                                                 }\r
2329                                                         }\r
2330                                                         this.listChip.Sort();\r
2331                                                 }\r
2332                                                 #endregion\r
2333                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2334                                                 //Trace.TraceInformation( "拍子・拍線挿入時間:       {0}", span.ToString() );\r
2335                                                 //timeBeginLoad = DateTime.Now;\r
2336                                                 #region [ C2 [拍線・小節線表示指定] の処理 ]               // #28145 2012.4.21 yyagi; 2重ループをほぼ1重にして高速化\r
2337                                                 bool bShowBeatBarLine = true;\r
2338                                                 for ( int i = 0; i < this.listChip.Count; i++ )\r
2339                                                 {\r
2340                                                         bool bChangedBeatBarStatus = false;\r
2341                                                         if ( ( this.listChip[ i ].nチャンネル番号 == 0xc2 ) )\r
2342                                                         {\r
2343                                                                 if ( this.listChip[ i ].n整数値 == 1 )                               // BAR/BEAT LINE = ON\r
2344                                                                 {\r
2345                                                                         bShowBeatBarLine = true;\r
2346                                                                         bChangedBeatBarStatus = true;\r
2347                                                                 }\r
2348                                                                 else if ( this.listChip[ i ].n整数値 == 2 )                  // BAR/BEAT LINE = OFF\r
2349                                                                 {\r
2350                                                                         bShowBeatBarLine = false;\r
2351                                                                         bChangedBeatBarStatus = true;\r
2352                                                                 }\r
2353                                                         }\r
2354                                                         int startIndex = i;\r
2355                                                         if ( bChangedBeatBarStatus )                                                    // C2チップの前に50/51チップが来ている可能性に配慮\r
2356                                                         {\r
2357                                                                 while ( startIndex > 0 && this.listChip[ startIndex ].n発声位置 == this.listChip[ i ].n発声位置 )\r
2358                                                                 {\r
2359                                                                         startIndex--;\r
2360                                                                 }\r
2361                                                                 startIndex++;   // 1つ小さく過ぎているので、戻す\r
2362                                                         }\r
2363                                                         for ( int j = startIndex; j <= i; j++ )\r
2364                                                         {\r
2365                                                                 if ( ( ( this.listChip[ j ].nチャンネル番号 == 0x50 ) || ( this.listChip[ j ].nチャンネル番号 == 0x51 ) ) &&\r
2366                                                                         ( this.listChip[ j ].n整数値 == ( 36 * 36 - 1 ) ) )\r
2367                                                                 {\r
2368                                                                         this.listChip[ j ].b可視 = bShowBeatBarLine;\r
2369                                                                 }\r
2370                                                         }\r
2371                                                 }\r
2372                                                 #endregion\r
2373                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2374                                                 //Trace.TraceInformation( "C2 [拍線・小節線表示指定]:  {0}", span.ToString() );\r
2375                                                 //timeBeginLoad = DateTime.Now;\r
2376                                                 #region [ 発声時刻の計算 ]\r
2377                                                 double bpm = 120.0;\r
2378                                                 double dbBarLength = 1.0;\r
2379                                                 int n発声位置 = 0;\r
2380                                                 int ms = 0;\r
2381                                                 int nBar = 0;\r
2382                                                 foreach ( CChip chip in this.listChip )\r
2383                                                 {\r
2384                                                         chip.n発声時刻ms = ms + ( (int) ( ( ( 0x271 * ( chip.n発声位置 - n発声位置 ) ) * dbBarLength ) / bpm ) );\r
2385                                                         if ( ( ( this.e種別 == E種別.BMS ) || ( this.e種別 == E種別.BME ) ) && ( ( dbBarLength != 1.0 ) && ( ( chip.n発声位置 / 384 ) != nBar ) ) )\r
2386                                                         {\r
2387                                                                 n発声位置 = chip.n発声位置;\r
2388                                                                 ms = chip.n発声時刻ms;\r
2389                                                                 dbBarLength = 1.0;\r
2390                                                         }\r
2391                                                         nBar = chip.n発声位置 / 384;\r
2392                                                         ch = chip.nチャンネル番号;\r
2393                                                         switch ( ch )\r
2394                                                         {\r
2395                                                                 case 0x02:      // BarLength\r
2396                                                                         {\r
2397                                                                                 n発声位置 = chip.n発声位置;\r
2398                                                                                 ms = chip.n発声時刻ms;\r
2399                                                                                 dbBarLength = chip.db実数値;\r
2400                                                                                 continue;\r
2401                                                                         }\r
2402                                                                 case 0x03:      // BPM\r
2403                                                                         {\r
2404                                                                                 n発声位置 = chip.n発声位置;\r
2405                                                                                 ms = chip.n発声時刻ms;\r
2406                                                                                 bpm = this.BASEBPM + chip.n整数値;\r
2407                                                                                 continue;\r
2408                                                                         }\r
2409                                                                 case 0x04:      // BGA (レイヤBGA1)\r
2410                                                                 case 0x07:      // レイヤBGA2\r
2411                                                                 case 0x55:      // レイヤBGA3\r
2412                                                                 case 0x56:      // レイヤBGA4\r
2413                                                                 case 0x57:      // レイヤBGA5\r
2414                                                                 case 0x58:      // レイヤBGA6\r
2415                                                                 case 0x59:      // レイヤBGA7\r
2416                                                                 case 0x60:      // レイヤBGA8\r
2417                                                                         break;\r
2418 \r
2419                                                                 case 0x05:      // Extended Object (非対応)\r
2420                                                                 case 0x06:      // Missアニメ (非対応)\r
2421                                                                 case 0x5A:      // 未定義\r
2422                                                                 case 0x5b:      // 未定義\r
2423                                                                 case 0x5c:      // 未定義\r
2424                                                                 case 0x5d:      // 未定義\r
2425                                                                 case 0x5e:      // 未定義\r
2426                                                                 case 0x5f:      // 未定義\r
2427                                                                         {\r
2428                                                                                 continue;\r
2429                                                                         }\r
2430                                                                 case 0x08:      // 拡張BPM\r
2431                                                                         {\r
2432                                                                                 n発声位置 = chip.n発声位置;\r
2433                                                                                 ms = chip.n発声時刻ms;\r
2434                                                                                 if ( this.listBPM.ContainsKey( chip.n整数値・内部番号 ) )\r
2435                                                                                 {\r
2436                                                                                         bpm = ( ( this.listBPM[ chip.n整数値・内部番号 ].n表記上の番号 == 0 ) ? 0.0 : this.BASEBPM ) + this.listBPM[ chip.n整数値・内部番号 ].dbBPM値;\r
2437                                                                                 }\r
2438                                                                                 continue;\r
2439                                                                         }\r
2440                                                                 case 0x54:      // 動画再生\r
2441                                                                         {\r
2442                                                                                 if ( this.listAVIPAN.ContainsKey( chip.n整数値 ) )\r
2443                                                                                 {\r
2444                                                                                         int num21 = ms + ( (int) ( ( ( 0x271 * ( chip.n発声位置 - n発声位置 ) ) * dbBarLength ) / bpm ) );\r
2445                                                                                         int num22 = ms + ( (int) ( ( ( 0x271 * ( ( chip.n発声位置 + this.listAVIPAN[ chip.n整数値 ].n移動時間ct ) - n発声位置 ) ) * dbBarLength ) / bpm ) );\r
2446                                                                                         chip.n総移動時間 = num22 - num21;\r
2447                                                                                 }\r
2448                                                                                 continue;\r
2449                                                                         }\r
2450                                                                 default:\r
2451                                                                         {\r
2452                                                                                 continue;\r
2453                                                                         }\r
2454                                                         }\r
2455                                                         if ( this.listBGAPAN.ContainsKey( chip.n整数値 ) )\r
2456                                                         {\r
2457                                                                 int num19 = ms + ( (int) ( ( ( 0x271 * ( chip.n発声位置 - n発声位置 ) ) * dbBarLength ) / bpm ) );\r
2458                                                                 int num20 = ms + ( (int) ( ( ( 0x271 * ( ( chip.n発声位置 + this.listBGAPAN[ chip.n整数値 ].n移動時間ct ) - n発声位置 ) ) * dbBarLength ) / bpm ) );\r
2459                                                                 chip.n総移動時間 = num20 - num19;\r
2460                                                         }\r
2461                                                 }\r
2462                                                 if ( this.db再生速度 > 0.0 )\r
2463                                                 {\r
2464                                                         double _db再生速度 = ( CDTXMania.DTXVmode.Enabled ) ? this.dbDTXVPlaySpeed : this.db再生速度;\r
2465                                                         foreach ( CChip chip in this.listChip )\r
2466                                                         {\r
2467                                                                 chip.n発声時刻ms = (int) ( ( (double) chip.n発声時刻ms ) / _db再生速度 );\r
2468                                                         }\r
2469                                                 }\r
2470                                                 #endregion\r
2471                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2472                                                 //Trace.TraceInformation( "発声時刻計算:             {0}", span.ToString() );\r
2473                                                 //timeBeginLoad = DateTime.Now;\r
2474                                                 this.nBGMAdjust = 0;\r
2475                                                 this.t各自動再生音チップの再生時刻を変更する( nBGMAdjust );\r
2476                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2477                                                 //Trace.TraceInformation( "再生時刻変更:             {0}", span.ToString() );\r
2478                                                 //timeBeginLoad = DateTime.Now;\r
2479                                                 #region [ 可視チップ数カウント ]\r
2480                                                 for ( int n = 0; n < 12; n++ )\r
2481                                                 {\r
2482                                                         this.n可視チップ数[ n ] = 0;\r
2483                                                 }\r
2484                                                 foreach ( CChip chip in this.listChip )\r
2485                                                 {\r
2486                                                         int c = chip.nチャンネル番号;\r
2487                                                         if ( ( 0x11 <= c ) && ( c <= 0x1a ) )\r
2488                                                         {\r
2489                                                                 this.n可視チップ数[ c - 0x11 ]++;\r
2490                                                         }\r
2491                                                         if ( ( 0x20 <= c ) && ( c <= 0x27 ) )\r
2492                                                         {\r
2493                                                                 this.n可視チップ数.Guitar++;\r
2494                                                         }\r
2495                                                         if ( ( 0xA0 <= c ) && ( c <= 0xa7 ) )\r
2496                                                         {\r
2497                                                                 this.n可視チップ数.Bass++;\r
2498                                                         }\r
2499                                                 }\r
2500                                                 #endregion\r
2501                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2502                                                 //Trace.TraceInformation( "可視チップ数カウント      {0}", span.ToString() );\r
2503                                                 //timeBeginLoad = DateTime.Now;\r
2504                                                 #region [ チップの種類を分類し、対応するフラグを立てる ]\r
2505                                                 foreach ( CChip chip in this.listChip )\r
2506                                                 {\r
2507                                                         if ( ( chip.bWAVを使うチャンネルである && this.listWAV.ContainsKey( chip.n整数値・内部番号 ) ) && !this.listWAV[ chip.n整数値・内部番号 ].listこのWAVを使用するチャンネル番号の集合.Contains( chip.nチャンネル番号 ) )\r
2508                                                         {\r
2509                                                                 this.listWAV[ chip.n整数値・内部番号 ].listこのWAVを使用するチャンネル番号の集合.Add( chip.nチャンネル番号 );\r
2510 \r
2511                                                                 int c = chip.nチャンネル番号 >> 4;\r
2512                                                                 switch ( c )\r
2513                                                                 {\r
2514                                                                         case 0x01:\r
2515                                                                                 this.listWAV[ chip.n整数値・内部番号 ].bIsDrumsSound = true; break;\r
2516                                                                         case 0x02:\r
2517                                                                                 this.listWAV[ chip.n整数値・内部番号 ].bIsGuitarSound = true; break;\r
2518                                                                         case 0x0A:\r
2519                                                                                 this.listWAV[ chip.n整数値・内部番号 ].bIsBassSound = true; break;\r
2520                                                                         case 0x06:\r
2521                                                                         case 0x07:\r
2522                                                                         case 0x08:\r
2523                                                                         case 0x09:\r
2524                                                                                 this.listWAV[ chip.n整数値・内部番号 ].bIsSESound = true; break;\r
2525                                                                         case 0x00:\r
2526                                                                                 if ( chip.nチャンネル番号 == 0x01 )\r
2527                                                                                 {\r
2528                                                                                         this.listWAV[ chip.n整数値・内部番号 ].bIsBGMSound = true; break;\r
2529                                                                                 }\r
2530                                                                                 break;\r
2531                                                                 }\r
2532                                                         }\r
2533                                                 }\r
2534                                                 #endregion\r
2535                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2536                                                 //Trace.TraceInformation( "ch番号集合確認:           {0}", span.ToString() );\r
2537                                                 //timeBeginLoad = DateTime.Now;\r
2538                                                 #region [ hash値計算 ]\r
2539                                                 byte[] buffer = null;\r
2540                                                 try\r
2541                                                 {\r
2542                                                         FileStream stream = new FileStream( this.strファイル名の絶対パス, FileMode.Open, FileAccess.Read );\r
2543                                                         buffer = new byte[ stream.Length ];\r
2544                                                         stream.Read( buffer, 0, (int) stream.Length );\r
2545                                                         stream.Close();\r
2546                                                 }\r
2547                                                 catch ( Exception exception )\r
2548                                                 {\r
2549                                                         Trace.TraceError( exception.Message );\r
2550                                                         Trace.TraceError( "DTXのハッシュの計算に失敗しました。({0})", this.strファイル名の絶対パス );\r
2551                                                 }\r
2552                                                 if ( buffer != null )\r
2553                                                 {\r
2554                                                         byte[] buffer2 = new MD5CryptoServiceProvider().ComputeHash( buffer );\r
2555                                                         StringBuilder sb = new StringBuilder();\r
2556                                                         foreach ( byte b in buffer2 )\r
2557                                                         {\r
2558                                                                 sb.Append( b.ToString( "x2" ) );\r
2559                                                         }\r
2560                                                         this.strハッシュofDTXファイル = sb.ToString();\r
2561                                                 }\r
2562                                                 else\r
2563                                                 {\r
2564                                                         this.strハッシュofDTXファイル = "00000000000000000000000000000000";\r
2565                                                 }\r
2566                                                 #endregion\r
2567                                                 //span = (TimeSpan) ( DateTime.Now - timeBeginLoad );\r
2568                                                 //Trace.TraceInformation( "hash計算:                 {0}", span.ToString() );\r
2569                                                 //timeBeginLoad = DateTime.Now;\r
2570                                                 #region [ bLogDTX詳細ログ出力 ]\r
2571                                                 if ( CDTXMania.ConfigIni.bLogDTX詳細ログ出力 )\r
2572                                                 {\r
2573                                                         foreach ( CWAV cwav in this.listWAV.Values )\r
2574                                                         {\r
2575                                                                 Trace.TraceInformation( cwav.ToString() );\r
2576                                                         }\r
2577                                                         foreach ( CAVI cavi in this.listAVI.Values )\r
2578                                                         {\r
2579                                                                 Trace.TraceInformation( cavi.ToString() );\r
2580                                                         }\r
2581                                                         foreach ( CAVIPAN cavipan in this.listAVIPAN.Values )\r
2582                                                         {\r
2583                                                                 Trace.TraceInformation( cavipan.ToString() );\r
2584                                                         }\r
2585                                                         foreach ( CBGA cbga in this.listBGA.Values )\r
2586                                                         {\r
2587                                                                 Trace.TraceInformation( cbga.ToString() );\r
2588                                                         }\r
2589                                                         foreach ( CBGAPAN cbgapan in this.listBGAPAN.Values )\r
2590                                                         {\r
2591                                                                 Trace.TraceInformation( cbgapan.ToString() );\r
2592                                                         }\r
2593                                                         foreach ( CBMP cbmp in this.listBMP.Values )\r
2594                                                         {\r
2595                                                                 Trace.TraceInformation( cbmp.ToString() );\r
2596                                                         }\r
2597                                                         foreach ( CBMPTEX cbmptex in this.listBMPTEX.Values )\r
2598                                                         {\r
2599                                                                 Trace.TraceInformation( cbmptex.ToString() );\r
2600                                                         }\r
2601                                                         foreach ( CBPM cbpm3 in this.listBPM.Values )\r
2602                                                         {\r
2603                                                                 Trace.TraceInformation( cbpm3.ToString() );\r
2604                                                         }\r
2605                                                         foreach ( CChip chip in this.listChip )\r
2606                                                         {\r
2607                                                                 Trace.TraceInformation( chip.ToString() );\r
2608                                                         }\r
2609                                                 }\r
2610                                                 #endregion\r
2611                                         }\r
2612                                 }\r
2613                         }\r
2614                 }\r
2615                 /// <summary>\r
2616                 /// サウンドミキサーにサウンドを登録・削除する時刻を事前に算出する\r
2617                 /// </summary>\r
2618                 public void PlanToAddMixerChannel()\r
2619                 {\r
2620                         if ( CDTXMania.Sound管理.GetCurrentSoundDeviceType() == "DirectSound" )       // DShowでの再生の場合はミキシング負荷が高くないため、\r
2621                         {                                                                                                                                               // チップのライフタイム管理を行わない\r
2622                                 return;\r
2623                         }\r
2624 \r
2625                         List<CChip> listAddMixerChannel = new List<CChip>( 128 ); ;\r
2626                         List<CChip> listRemoveMixerChannel = new List<CChip>( 128 );\r
2627                         List<CChip> listRemoveTiming = new List<CChip>( 128 );\r
2628 \r
2629                         foreach ( CChip pChip in listChip )\r
2630                         {\r
2631                                 switch ( pChip.nチャンネル番号 )\r
2632                                 {\r
2633                                         // BGM, 演奏チャネル, 不可視サウンド, フィルインサウンド, 空打ち音はミキサー管理の対象\r
2634                                         // BGM:\r
2635                                         case 0x01:\r
2636                                         // Dr演奏チャネル\r
2637                                         case 0x11:      case 0x12:      case 0x13:      case 0x14:      case 0x15:      case 0x16:      case 0x17:      case 0x18:      case 0x19:      case 0x1A:\r
2638                                         // Gt演奏チャネル\r
2639                                         case 0x20:      case 0x21:      case 0x22:      case 0x23:      case 0x24:      case 0x25:      case 0x26:      case 0x27:      case 0x28:\r
2640                                         // Bs演奏チャネル\r
2641                                         case 0xA0:      case 0xA1:      case 0xA2:      case 0xA3:      case 0xA4:      case 0xA5:      case 0xA6:      case 0xA7:      case 0xA8:\r
2642                                         // Dr不可視チップ\r
2643                                         case 0x31:      case 0x32:      case 0x33:      case 0x34:      case 0x35:      case 0x36:      case 0x37:\r
2644                                         case 0x38:      case 0x39:      case 0x3A:\r
2645                                         // Dr/Gt/Bs空打ち\r
2646                                         case 0xB1:      case 0xB2:      case 0xB3:      case 0xB4:      case 0xB5:      case 0xB6:      case 0xB7:      case 0xB8:\r
2647                                         case 0xB9:      case 0xBA:      case 0xBB:      case 0xBC:\r
2648                                         // フィルインサウンド\r
2649                                         case 0x1F:      case 0x2F:      case 0xAF:\r
2650                                         // 自動演奏チップ\r
2651                                         case 0x61:      case 0x62:      case 0x63:      case 0x64:      case 0x65:      case 0x66:      case 0x67:      case 0x68:      case 0x69:\r
2652                                         case 0x70:      case 0x71:      case 0x72:      case 0x73:      case 0x74:      case 0x75:      case 0x76:      case 0x77:      case 0x78:      case 0x79:\r
2653                                         case 0x80:      case 0x81:      case 0x82:      case 0x83:      case 0x84:      case 0x85:      case 0x86:      case 0x87:      case 0x88:      case 0x89:\r
2654                                         case 0x90:      case 0x91:      case 0x92:\r
2655 \r
2656                                                 #region [ 発音1秒前のタイミングを記録 ]\r
2657                                                 int n発音前余裕ms = 1000, n発音後余裕ms = 800;\r
2658                                                 {\r
2659                                                         int ch = pChip.nチャンネル番号 >> 4;\r
2660                                                         if ( ch == 0x02 || ch == 0x0A )\r
2661                                                         {\r
2662                                                                 n発音前余裕ms = 800;\r
2663                                                                 n発音前余裕ms = 500;\r
2664                                                         }\r
2665                                                         if ( ch == 0x06 || ch == 0x07 || ch == 0x08 || ch == 0x09 )\r
2666                                                         {\r
2667                                                                 n発音前余裕ms = 200;\r
2668                                                                 n発音前余裕ms = 500;\r
2669                                                         }\r
2670                                                 }\r
2671                                                 if ( pChip.nチャンネル番号 == 0x01 )     // BGMチップは即ミキサーに追加\r
2672                                                 {\r
2673                                                         if ( listWAV.ContainsKey( pChip.n整数値・内部番号 ) )\r
2674                                                         {\r
2675                                                                 CDTX.CWAV wc = CDTXMania.DTX.listWAV[ pChip.n整数値・内部番号 ];\r
2676                                                                 if ( wc.rSound[ 0 ] != null )\r
2677                                                                 {\r
2678                                                                         CDTXMania.Sound管理.AddMixer( wc.rSound[ 0 ] );       // BGMは多重再生しない仕様としているので、1個目だけミキサーに登録すればよい\r
2679                                                                 }\r
2680                                                         }\r
2681 \r
2682                                                 }\r
2683 \r
2684                                                 int nAddMixer時刻ms, nAddMixer位置 = 0;\r
2685 //Debug.WriteLine("==================================================================");\r
2686 //Debug.WriteLine( "Start: ch=" + pChip.nチャンネル番号.ToString("x2") + ", nWAV番号=" + pChip.n整数値 + ", time=" + pChip.n発声時刻ms + ", lasttime=" + listChip[ listChip.Count - 1 ].n発声時刻ms );\r
2687                                                 t発声時刻msと発声位置を取得する( pChip.n発声時刻ms - n発音前余裕ms, out nAddMixer時刻ms, out nAddMixer位置 );\r
2688 //Debug.WriteLine( "nAddMixer時刻ms=" + nAddMixer時刻ms + ",nAddMixer位置=" + nAddMixer位置 );\r
2689 \r
2690                                                 CChip c_AddMixer = new CChip()\r
2691                                                 {\r
2692                                                         nチャンネル番号 = 0xDA,\r
2693                                                         n整数値 = pChip.n整数値,\r
2694                                                         n整数値・内部番号 = pChip.n整数値・内部番号,\r
2695                                                         n発声時刻ms = nAddMixer時刻ms,\r
2696                                                         n発声位置 = nAddMixer位置,\r
2697                                                         b演奏終了後も再生が続くチップである = false\r
2698                                                 };\r
2699                                                 listAddMixerChannel.Add( c_AddMixer );\r
2700 //Debug.WriteLine("listAddMixerChannel:" );\r
2701 //DebugOut_CChipList( listAddMixerChannel );\r
2702                                                 #endregion\r
2703 \r
2704                                                 int duration = 0;\r
2705                                                 if ( listWAV.ContainsKey( pChip.n整数値・内部番号 ) )\r
2706                                                 {\r
2707                                                         CDTX.CWAV wc = CDTXMania.DTX.listWAV[ pChip.n整数値・内部番号 ];\r
2708                                                         duration = ( wc.rSound[ 0 ] == null ) ? 0 : (int) ( wc.rSound[ 0 ].n総演奏時間ms / this.db再生速度 );  // #23664 durationに再生速度が加味されておらず、低速再生でBGMが途切れる問題を修正 (発声時刻msは、DTX読み込み時に再生速度加味済)\r
2709                                                 }\r
2710 //Debug.WriteLine("duration=" + duration );\r
2711                                                 int n新RemoveMixer時刻ms, n新RemoveMixer位置;\r
2712                                                 t発声時刻msと発声位置を取得する( pChip.n発声時刻ms + duration + n発音後余裕ms, out n新RemoveMixer時刻ms, out n新RemoveMixer位置 );\r
2713 //Debug.WriteLine( "n新RemoveMixer時刻ms=" + n新RemoveMixer時刻ms + ",n新RemoveMixer位置=" + n新RemoveMixer位置 );\r
2714                                                 if ( n新RemoveMixer時刻ms < pChip.n発声時刻ms + duration )       // 曲の最後でサウンドが切れるような場合は\r
2715                                                 {\r
2716                                                         CChip c_AddMixer_noremove = c_AddMixer;\r
2717                                                         c_AddMixer_noremove.b演奏終了後も再生が続くチップである = true;\r
2718                                                         listAddMixerChannel[ listAddMixerChannel.Count - 1 ] = c_AddMixer_noremove;\r
2719                                                         //continue;                                                                                             // 発声位置の計算ができないので、Mixer削除をあきらめる・・・のではなく\r
2720                                                                                                                                                                         // #32248 2013.10.15 yyagi 演奏終了後も再生を続けるチップであるというフラグをpChip内に立てる\r
2721                                                         break;\r
2722                                                 }\r
2723                                                 #region [ 未使用コード ]\r
2724                                                 //if ( n新RemoveMixer時刻ms < pChip.n発声時刻ms + duration )     // 曲の最後でサウンドが切れるような場合\r
2725                                                 //{\r
2726                                                 //    n新RemoveMixer時刻ms = pChip.n発声時刻ms + duration;\r
2727                                                 //    // 「位置」は比例計算で求めてお茶を濁す...このやり方だと誤動作したため対応中止\r
2728                                                 //    n新RemoveMixer位置 = listChip[ listChip.Count - 1 ].n発声位置 * n新RemoveMixer時刻ms / listChip[ listChip.Count - 1 ].n発声時刻ms;\r
2729                                                 //}\r
2730                                                 #endregion\r
2731 \r
2732                                                 #region [ 発音終了2秒後にmixerから削除するが、その前に再発音することになるのかを確認(再発音ならmixer削除タイミングを延期) ]\r
2733                                                 int n整数値 = pChip.n整数値;\r
2734                                                 int index = listRemoveTiming.FindIndex(\r
2735                                                         delegate( CChip cchip ) { return cchip.n整数値 == n整数値; }\r
2736                                                 );\r
2737 //Debug.WriteLine( "index=" + index );\r
2738                                                 if ( index >= 0 )                                                                                                       // 過去に同じチップで発音中のものが見つかった場合\r
2739                                                 {                                                                                                                                       // 過去の発音のmixer削除を確定させるか、延期するかの2択。\r
2740                                                         int n旧RemoveMixer時刻ms = listRemoveTiming[ index ].n発声時刻ms;\r
2741                                                         int n旧RemoveMixer位置 = listRemoveTiming[ index ].n発声位置;\r
2742 \r
2743 //Debug.WriteLine( "n旧RemoveMixer時刻ms=" + n旧RemoveMixer時刻ms + ",n旧RemoveMixer位置=" + n旧RemoveMixer位置 );\r
2744                                                         if ( pChip.n発声時刻ms - n発音前余裕ms <= n旧RemoveMixer時刻ms )    // mixer削除前に、同じ音の再発音がある場合は、\r
2745                                                         {                                                                                                                                       // mixer削除時刻を遅延させる(if-else後に行う)\r
2746 //Debug.WriteLine( "remove TAIL of listAddMixerChannel. TAIL INDEX=" + listAddMixerChannel.Count );\r
2747 //DebugOut_CChipList( listAddMixerChannel );\r
2748                                                                 listAddMixerChannel.RemoveAt( listAddMixerChannel.Count - 1 );  // また、同じチップ音の「mixerへの再追加」は削除する\r
2749 //Debug.WriteLine( "removed result:" );\r
2750 //DebugOut_CChipList( listAddMixerChannel );\r
2751                                                         }\r
2752                                                         else                                                                                                                    // 逆に、時間軸上、mixer削除後に再発音するような流れの場合は\r
2753                                                         {\r
2754 //Debug.WriteLine( "Publish the value(listRemoveTiming[index] to listRemoveMixerChannel." );\r
2755                                                                 listRemoveMixerChannel.Add( listRemoveTiming[ index ] );        // mixer削除を確定させる\r
2756 //Debug.WriteLine( "listRemoveMixerChannel:" );\r
2757 //DebugOut_CChipList( listRemoveMixerChannel );\r
2758                                                                 //listRemoveTiming.RemoveAt( index );\r
2759                                                         }\r
2760                                                         CChip c = new CChip()                                                                                   // mixer削除時刻を更新(遅延)する\r
2761                                                         {\r
2762                                                                 nチャンネル番号 = 0xDB,\r
2763                                                                 n整数値 = listRemoveTiming[ index ].n整数値,\r
2764                                                                 n整数値・内部番号 = listRemoveTiming[ index ].n整数値・内部番号,\r
2765                                                                 n発声時刻ms = n新RemoveMixer時刻ms,\r
2766                                                                 n発声位置 = n新RemoveMixer位置\r
2767                                                         };\r
2768                                                         listRemoveTiming[ index ] = c;\r
2769                                                         //listRemoveTiming[ index ].n発声時刻ms = n新RemoveMixer時刻ms;  // mixer削除時刻を更新(遅延)する\r
2770                                                         //listRemoveTiming[ index ].n発声位置 = n新RemoveMixer位置;\r
2771 //Debug.WriteLine( "listRemoveTiming: modified" );\r
2772 //DebugOut_CChipList( listRemoveTiming );\r
2773                                                 }\r
2774                                                 else                                                                                                                            // 過去に同じチップを発音していないor\r
2775                                                 {                                                                                                                                       // 発音していたが既にmixer削除確定していたなら\r
2776                                                         CChip c = new CChip()                                                                                   // 新しくmixer削除候補として追加する\r
2777                                                         {\r
2778                                                                 nチャンネル番号 = 0xDB,\r
2779                                                                 n整数値 = pChip.n整数値,\r
2780                                                                 n整数値・内部番号 = pChip.n整数値・内部番号,\r
2781                                                                 n発声時刻ms = n新RemoveMixer時刻ms,\r
2782                                                                 n発声位置 = n新RemoveMixer位置\r
2783                                                         };\r
2784 //Debug.WriteLine( "Add new chip to listRemoveMixerTiming: " );\r
2785 //Debug.WriteLine( "ch=" + c.nチャンネル番号.ToString( "x2" ) + ", nWAV番号=" + c.n整数値 + ", time=" + c.n発声時刻ms + ", lasttime=" + listChip[ listChip.Count - 1 ].n発声時刻ms );\r
2786                                                         listRemoveTiming.Add( c );\r
2787 //Debug.WriteLine( "listRemoveTiming:" );\r
2788 //DebugOut_CChipList( listRemoveTiming );\r
2789                                                 }\r
2790                                                 #endregion\r
2791                                                 break;\r
2792                                 }\r
2793                         }\r
2794 //Debug.WriteLine("==================================================================");\r
2795 //Debug.WriteLine( "Result:" );\r
2796 //Debug.WriteLine( "listAddMixerChannel:" );\r
2797 //DebugOut_CChipList( listAddMixerChannel );\r
2798 //Debug.WriteLine( "listRemoveMixerChannel:" );\r
2799 //DebugOut_CChipList( listRemoveMixerChannel );\r
2800 //Debug.WriteLine( "listRemoveTiming:" );\r
2801 //DebugOut_CChipList( listRemoveTiming );\r
2802 //Debug.WriteLine( "==================================================================" );\r
2803 \r
2804                         listChip.AddRange( listAddMixerChannel );\r
2805                         listChip.AddRange( listRemoveMixerChannel );\r
2806                         listChip.AddRange( listRemoveTiming );\r
2807                         listChip.Sort();\r
2808                 }\r
2809                 private void DebugOut_CChipList( List<CChip> c )\r
2810                 {\r
2811 //Debug.WriteLine( "Count=" + c.Count );\r
2812                         for ( int i = 0; i < c.Count; i++ )\r
2813                         {\r
2814                                 Debug.WriteLine( i + ": ch=" + c[ i ].nチャンネル番号.ToString("x2") + ", WAV番号=" + c[ i ].n整数値 + ", time=" + c[ i ].n発声時刻ms );\r
2815                         }\r
2816                 }\r
2817                 private bool t発声時刻msと発声位置を取得する( int n希望発声時刻ms, out int n新発声時刻ms, out int n新発声位置 )\r
2818                 {\r
2819                         // 発声時刻msから発声位置を逆算することはできないため、近似計算する。\r
2820                         // 具体的には、希望発声位置前後の2つのチップの発声位置の中間を取る。\r
2821 \r
2822                         if ( n希望発声時刻ms < 0 )\r
2823                         {\r
2824                                 n希望発声時刻ms = 0;\r
2825                         }\r
2826                         //else if ( n希望発声時刻ms > listChip[ listChip.Count - 1 ].n発声時刻ms )            // BGMの最後の余韻を殺してしまうので、この条件は外す\r
2827                         //{\r
2828                         //    n希望発声時刻ms = listChip[ listChip.Count - 1 ].n発声時刻ms;\r
2829                         //}\r
2830 \r
2831                         int index_min = -1, index_max = -1;\r
2832                         for ( int i = 0; i < listChip.Count; i++ )              // 希望発声位置前後の「前」の方のチップを検索\r
2833                         {\r
2834                                 if ( listChip[ i ].n発声時刻ms >= n希望発声時刻ms )\r
2835                                 {\r
2836                                         index_min = i;\r
2837                                         break;\r
2838                                 }\r
2839                         }\r
2840                         if ( index_min < 0 )    // 希望発声時刻に至らずに曲が終了してしまう場合\r
2841                         {\r
2842                                 // listの最終項目の時刻をそのまま使用する\r
2843                                                                 //・・・のではダメ。BGMが尻切れになる。\r
2844                                                                 // そこで、listの最終項目の発声時刻msと発生位置から、希望発声時刻に相当する希望発声位置を比例計算して求める。\r
2845                                 //n新発声時刻ms = n希望発声時刻ms;\r
2846                                 //n新発声位置 = listChip[ listChip.Count - 1 ].n発声位置 * n希望発声時刻ms / listChip[ listChip.Count - 1 ].n発声時刻ms;\r
2847                                 n新発声時刻ms = listChip[ listChip.Count - 1 ].n発声時刻ms;\r
2848                                 n新発声位置   = listChip[ listChip.Count - 1 ].n発声位置;\r
2849                                 return false;\r
2850                         }\r
2851                         index_max = index_min + 1;\r
2852                         if ( index_max >= listChip.Count )\r
2853                         {\r
2854                                 index_max = index_min;\r
2855                         }\r
2856                         n新発声時刻ms = ( listChip[ index_max ].n発声時刻ms + listChip[ index_min ].n発声時刻ms ) / 2;\r
2857                         n新発声位置   = ( listChip[ index_max ].n発声位置   + listChip[ index_min ].n発声位置   ) / 2;\r
2858 \r
2859                         return true;\r
2860                 }\r
2861 \r
2862 \r
2863                 /// <summary>\r
2864                 /// Swap infos between Guitar and Bass (notes, level, n可視チップ数, bチップがある)\r
2865                 /// </summary>\r
2866                 public void SwapGuitarBassInfos()                                               // #24063 2011.1.24 yyagi ギターとベースの譜面情報入替\r
2867                 {\r
2868                         for (int i = this.listChip.Count - 1; i >= 0; i--) {\r
2869                                 if (listChip[i].e楽器パート == E楽器パート.BASS) {\r
2870                                         listChip[i].e楽器パート = E楽器パート.GUITAR;\r
2871                                         listChip[i].nチャンネル番号 -= ( 0xA0 - 0x20 );\r
2872                                 }\r
2873                                 else if ( listChip[i].e楽器パート == E楽器パート.GUITAR )\r
2874                                 {\r
2875                                         listChip[i].e楽器パート = E楽器パート.BASS;\r
2876                                         listChip[i].nチャンネル番号 += ( 0xA0 - 0x20 );\r
2877                                 }\r
2878                                 else if ( listChip[ i ].nチャンネル番号 == 0x28 )                // #25215 2011.5.21 yyagi wailingはE楽器パート.UNKNOWNが割り当てられているので個別に対応\r
2879                                 {\r
2880                                         listChip[ i ].nチャンネル番号 += ( 0xA0 - 0x20 );\r
2881                                 }\r
2882                                 else if ( listChip[ i ].nチャンネル番号 == 0xA8 )                // #25215 2011.5.21 yyagi wailingはE楽器パート.UNKNOWNが割り当てられているので個別に対応\r
2883                                 {\r
2884                                         listChip[ i ].nチャンネル番号 -= ( 0xA0 - 0x20 );\r
2885                                 }\r
2886                         }\r
2887                         int t = this.LEVEL.Bass;\r
2888                         this.LEVEL.Bass = this.LEVEL.Guitar;\r
2889                         this.LEVEL.Guitar = t;\r
2890 \r
2891                         t = this.n可視チップ数.Bass;\r
2892                         this.n可視チップ数.Bass = this.n可視チップ数.Guitar;\r
2893                         this.n可視チップ数.Guitar = t;\r
2894 \r
2895                         bool ts = this.bチップがある.Bass;\r
2896                         this.bチップがある.Bass = this.bチップがある.Guitar;\r
2897                         this.bチップがある.Guitar = ts;\r
2898 \r
2899 //                      SwapGuitarBassInfos_AutoFlags();\r
2900                 }\r
2901 \r
2902                 // SwapGuitarBassInfos_AutoFlags()は、CDTXからCConfigIniに移動。\r
2903 \r
2904                 // CActivity 実装\r
2905 \r
2906                 public override void On活性化()\r
2907                 {\r
2908                         this.listWAV = new Dictionary<int, CWAV>();\r
2909                         this.listBMP = new Dictionary<int, CBMP>();\r
2910                         this.listBMPTEX = new Dictionary<int, CBMPTEX>();\r
2911                         this.listBPM = new Dictionary<int, CBPM>();\r
2912                         this.listBGAPAN = new Dictionary<int, CBGAPAN>();\r
2913                         this.listBGA = new Dictionary<int, CBGA>();\r
2914                         this.listAVIPAN = new Dictionary<int, CAVIPAN>();\r
2915                         this.listAVI = new Dictionary<int, CAVI>();\r
2916                         this.listChip = new List<CChip>();\r
2917                         base.On活性化();\r
2918                 }\r
2919                 public override void On非活性化()\r
2920                 {\r
2921                         if( this.listWAV != null )\r
2922                         {\r
2923                                 foreach( CWAV cwav in this.listWAV.Values )\r
2924                                 {\r
2925                                         cwav.Dispose();\r
2926                                 }\r
2927                                 this.listWAV = null;\r
2928                         }\r
2929                         if( this.listBMP != null )\r
2930                         {\r
2931                                 foreach( CBMP cbmp in this.listBMP.Values )\r
2932                                 {\r
2933                                         cbmp.Dispose();\r
2934                                 }\r
2935                                 this.listBMP = null;\r
2936                         }\r
2937                         if( this.listBMPTEX != null )\r
2938                         {\r
2939                                 foreach( CBMPTEX cbmptex in this.listBMPTEX.Values )\r
2940                                 {\r
2941                                         cbmptex.Dispose();\r
2942                                 }\r
2943                                 this.listBMPTEX = null;\r
2944                         }\r
2945                         if( this.listAVI != null )\r
2946                         {\r
2947                                 foreach( CAVI cavi in this.listAVI.Values )\r
2948                                 {\r
2949                                         cavi.Dispose();\r
2950                                 }\r
2951                                 this.listAVI = null;\r
2952                         }\r
2953                         if( this.listBPM != null )\r
2954                         {\r
2955                                 this.listBPM.Clear();\r
2956                                 this.listBPM = null;\r
2957                         }\r
2958                         if( this.listBGAPAN != null )\r
2959                         {\r
2960                                 this.listBGAPAN.Clear();\r
2961                                 this.listBGAPAN = null;\r
2962                         }\r
2963                         if( this.listBGA != null )\r
2964                         {\r
2965                                 this.listBGA.Clear();\r
2966                                 this.listBGA = null;\r
2967                         }\r
2968                         if( this.listAVIPAN != null )\r
2969                         {\r
2970                                 this.listAVIPAN.Clear();\r
2971                                 this.listAVIPAN = null;\r
2972                         }\r
2973                         if( this.listChip != null )\r
2974                         {\r
2975                                 this.listChip.Clear();\r
2976                         }\r
2977                         base.On非活性化();\r
2978                 }\r
2979                 public override void OnManagedリソースの作成()\r
2980                 {\r
2981                         if( !base.b活性化してない )\r
2982                         {\r
2983                                 this.tBMP_BMPTEXの読み込み();\r
2984                                 this.tAVIの読み込み();\r
2985                                 base.OnManagedリソースの作成();\r
2986                         }\r
2987                 }\r
2988                 public override void OnManagedリソースの解放()\r
2989                 {\r
2990                         if( !base.b活性化してない )\r
2991                         {\r
2992                                 if( this.listBMP != null )\r
2993                                 {\r
2994                                         foreach( CBMP cbmp in this.listBMP.Values )\r
2995                                         {\r
2996                                                 cbmp.Dispose();\r
2997                                         }\r
2998                                 }\r
2999                                 if( this.listBMPTEX != null )\r
3000                                 {\r
3001                                         foreach( CBMPTEX cbmptex in this.listBMPTEX.Values )\r
3002                                         {\r
3003                                                 cbmptex.Dispose();\r
3004                                         }\r
3005                                 }\r
3006                                 if( this.listAVI != null )\r
3007                                 {\r
3008                                         foreach( CAVI cavi in this.listAVI.Values )\r
3009                                         {\r
3010                                                 cavi.Dispose();\r
3011                                         }\r
3012                                 }\r
3013                                 base.OnManagedリソースの解放();\r
3014                         }\r
3015                 }\r
3016 \r
3017 \r
3018                 // その他\r
3019                 \r
3020                 #region [ private ]\r
3021                 //-----------------\r
3022                 /// <summary>\r
3023                 /// <para>GDAチャンネル番号に対応するDTXチャンネル番号。</para>\r
3024                 /// </summary>\r
3025                 [StructLayout( LayoutKind.Sequential )]\r
3026                 private struct STGDAPARAM\r
3027                 {\r
3028                         public string strGDAのチャンネル文字列;        \r
3029                         public int nDTXのチャンネル番号;\r
3030 \r
3031                         public STGDAPARAM( string strGDAのチャンネル文字列, int nDTXのチャンネル番号 )         // 2011.1.1 yyagi 構造体のコンストラクタ追加(初期化簡易化のため)\r
3032                         {\r
3033                                 this.strGDAのチャンネル文字列 = strGDAのチャンネル文字列;\r
3034                                 this.nDTXのチャンネル番号 = nDTXのチャンネル番号;\r
3035                         }\r
3036                 }\r
3037 \r
3038                 private readonly STGDAPARAM[] stGDAParam;\r
3039                 private bool bヘッダのみ;\r
3040                 private Stack<bool> bstackIFからENDIFをスキップする;\r
3041         \r
3042                 private int n現在の行数;\r
3043                 private int n現在の乱数;\r
3044 \r
3045                 private int nPolyphonicSounds = 4;                                                      // #28228 2012.5.1 yyagi\r
3046 \r
3047                 private int n内部番号BPM1to;\r
3048                 private int n内部番号WAV1to;\r
3049                 private int[] n無限管理BPM;\r
3050                 private int[] n無限管理PAN;\r
3051                 private int[] n無限管理SIZE;\r
3052                 private int[] n無限管理VOL;\r
3053                 private int[] n無限管理WAV;\r
3054                 private int[] nRESULTIMAGE用優先順位;\r
3055                 private int[] nRESULTMOVIE用優先順位;\r
3056                 private int[] nRESULTSOUND用優先順位;\r
3057 \r
3058                 private bool t入力・コマンド文字列を抜き出す( ref CharEnumerator ce, ref StringBuilder sb文字列 )\r
3059                 {\r
3060                         if( !this.t入力・空白をスキップする( ref ce ) )\r
3061                                 return false;   // 文字が尽きた\r
3062 \r
3063                         #region [ コマンド終端文字(':')、半角空白、コメント開始文字(';')、改行のいずれかが出現するまでをコマンド文字列と見なし、sb文字列 にコピーする。]\r
3064                         //-----------------\r
3065                         while( ce.Current != ':' && ce.Current != ' ' && ce.Current != ';' && ce.Current != '\n' )\r
3066                         {\r
3067                                 sb文字列.Append( ce.Current );\r
3068 \r
3069                                 if( !ce.MoveNext() )\r
3070                                         return false;   // 文字が尽きた\r
3071                         }\r
3072                         //-----------------\r
3073                         #endregion\r
3074 \r
3075                         #region [ コマンド終端文字(':')で終端したなら、その次から空白をスキップしておく。]\r
3076                         //-----------------\r
3077                         if( ce.Current == ':' )\r
3078                         {\r
3079                                 if( !ce.MoveNext() )\r
3080                                         return false;   // 文字が尽きた\r
3081 \r
3082                                 if( !this.t入力・空白をスキップする( ref ce ) )\r
3083                                         return false;   // 文字が尽きた\r
3084                         }\r
3085                         //-----------------\r
3086                         #endregion\r
3087 \r
3088                         return true;\r
3089                 }\r
3090                 private bool t入力・コメントをスキップする( ref CharEnumerator ce )\r
3091                 {\r
3092                         // 改行が現れるまでをコメントと見なしてスキップする。\r
3093 \r
3094                         while( ce.Current != '\n' )\r
3095                         {\r
3096                                 if( !ce.MoveNext() )\r
3097                                         return false;   // 文字が尽きた\r
3098                         }\r
3099 \r
3100                         // 改行の次の文字へ移動した結果を返す。\r
3101 \r
3102                         return ce.MoveNext();\r
3103                 }\r
3104                 private bool t入力・コメント文字列を抜き出す( ref CharEnumerator ce, ref StringBuilder sb文字列 )\r
3105                 {\r
3106                         if( ce.Current != ';' )         // コメント開始文字(';')じゃなければ正常帰還。\r
3107                                 return true;\r
3108 \r
3109                         if( !ce.MoveNext() )            // ';' の次で文字列が終わってたら終了帰還。\r
3110                                 return false;\r
3111 \r
3112                         #region [ ';' の次の文字から '\n' の1つ前までをコメント文字列と見なし、sb文字列にコピーする。]\r
3113                         //-----------------\r
3114                         while( ce.Current != '\n' )\r
3115                         {\r
3116                                 sb文字列.Append( ce.Current );\r
3117 \r
3118                                 if( !ce.MoveNext() )\r
3119                                         return false;\r
3120                         }\r
3121                         //-----------------\r
3122                         #endregion\r
3123 \r
3124                         return true;\r
3125                 }\r
3126                 private void t入力・パラメータ食い込みチェック( string strコマンド名, ref string strコマンド, ref string strパラメータ )\r
3127                 {\r
3128                         if( ( strコマンド.Length > strコマンド名.Length ) && strコマンド.StartsWith( strコマンド名, StringComparison.OrdinalIgnoreCase ) )\r
3129                         {\r
3130                                 strパラメータ = strコマンド.Substring( strコマンド名.Length ).Trim();\r
3131                                 strコマンド = strコマンド.Substring( 0, strコマンド名.Length );\r
3132                         }\r
3133                 }\r
3134                 private bool t入力・パラメータ文字列を抜き出す( ref CharEnumerator ce, ref StringBuilder sb文字列 )\r
3135                 {\r
3136                         if( !this.t入力・空白をスキップする( ref ce ) )\r
3137                                 return false;   // 文字が尽きた\r
3138 \r
3139                         #region [ 改行またはコメント開始文字(';')が出現するまでをパラメータ文字列と見なし、sb文字列 にコピーする。]\r
3140                         //-----------------\r
3141                         while( ce.Current != '\n' && ce.Current != ';' )\r
3142                         {\r
3143                                 sb文字列.Append( ce.Current );\r
3144 \r
3145                                 if( !ce.MoveNext() )\r
3146                                         return false;\r
3147                         }\r
3148                         //-----------------\r
3149                         #endregion\r
3150 \r
3151                         return true;\r
3152                 }\r
3153                 private bool t入力・空白と改行をスキップする( ref CharEnumerator ce )\r
3154                 {\r
3155                         // 空白と改行が続く間はこれらをスキップする。\r
3156 \r
3157                         while( ce.Current == ' ' || ce.Current == '\n' )\r
3158                         {\r
3159                                 if( ce.Current == '\n' )\r
3160                                         this.n現在の行数++;                // 改行文字では行番号が増える。\r
3161 \r
3162                                 if( !ce.MoveNext() )\r
3163                                         return false;   // 文字が尽きた\r
3164                         }\r
3165 \r
3166                         return true;\r
3167                 }\r
3168                 private bool t入力・空白をスキップする( ref CharEnumerator ce )\r
3169                 {\r
3170                         // 空白が続く間はこれをスキップする。\r
3171 \r
3172                         while( ce.Current == ' ' )\r
3173                         {\r
3174                                 if( !ce.MoveNext() )\r
3175                                         return false;   // 文字が尽きた\r
3176                         }\r
3177 \r
3178                         return true;\r
3179                 }\r
3180                 private void t入力・行解析( ref StringBuilder sbコマンド, ref StringBuilder sbパラメータ, ref StringBuilder sbコメント )\r
3181                 {\r
3182                         string strコマンド = sbコマンド.ToString();\r
3183                         string strパラメータ = sbパラメータ.ToString().Trim();\r
3184                         string strコメント = sbコメント.ToString();\r
3185 \r
3186                         // 行頭コマンドの処理\r
3187 \r
3188                         #region [ IF ]\r
3189                         //-----------------\r
3190                         if( strコマンド.StartsWith( "IF", StringComparison.OrdinalIgnoreCase ) )\r
3191                         {\r
3192                                 this.t入力・パラメータ食い込みチェック( "IF", ref strコマンド, ref strパラメータ );\r
3193 \r
3194                                 if( this.bstackIFからENDIFをスキップする.Count == 255 )\r
3195                                 {\r
3196                                         Trace.TraceWarning( "#IF の入れ子の数が 255 を超えました。この #IF を無視します。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
3197                                 }\r
3198                                 else if( this.bstackIFからENDIFをスキップする.Peek() )\r
3199                                 {\r
3200                                         this.bstackIFからENDIFをスキップする.Push( true );     // 親が true ならその入れ子も問答無用で true 。\r
3201                                 }\r
3202                                 else                                                                                                    // 親が false なら入れ子はパラメータと乱数を比較して結果を判断する。\r
3203                                 {\r
3204                                         int n数値 = 0;\r
3205 \r
3206                                         if( !int.TryParse( strパラメータ, out n数値 ) )\r
3207                                                 n数値 = 1;\r
3208 \r
3209                                         this.bstackIFからENDIFをスキップする.Push( n数値 != this.n現在の乱数 );         // 乱数と数値が一致したら true 。\r
3210                                 }\r
3211                         }\r
3212                         //-----------------\r
3213                         #endregion\r
3214                         #region [ ENDIF ]\r
3215                         //-----------------\r
3216                         else if( strコマンド.StartsWith( "ENDIF", StringComparison.OrdinalIgnoreCase ) )\r
3217                         {\r
3218                                 this.t入力・パラメータ食い込みチェック( "ENDIF", ref strコマンド, ref strパラメータ );\r
3219 \r
3220                                 if( this.bstackIFからENDIFをスキップする.Count > 1 )\r
3221                                 {\r
3222                                         this.bstackIFからENDIFをスキップする.Pop();            // 入れ子を1つ脱出。\r
3223                                 }\r
3224                                 else\r
3225                                 {\r
3226                                         Trace.TraceWarning( "#ENDIF に対応する #IF がありません。この #ENDIF を無視します。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
3227                                 }\r
3228                         }\r
3229                         //-----------------\r
3230                         #endregion\r
3231 \r
3232                         else if( !this.bstackIFからENDIFをスキップする.Peek() )                // IF~ENDIF をスキップするなら以下はすべて無視。\r
3233                         {\r
3234                                 #region [ PATH_WAV ]\r
3235                                 //-----------------\r
3236                                 if( strコマンド.StartsWith( "PATH_WAV", StringComparison.OrdinalIgnoreCase ) )\r
3237                                 {\r
3238                                         this.t入力・パラメータ食い込みチェック( "PATH_WAV", ref strコマンド, ref strパラメータ );\r
3239                                         this.PATH_WAV = strパラメータ;\r
3240                                 }\r
3241                                 //-----------------\r
3242                                 #endregion\r
3243                                 #region [ TITLE ]\r
3244                                 //-----------------\r
3245                                 else if( strコマンド.StartsWith( "TITLE", StringComparison.OrdinalIgnoreCase ) )\r
3246                                 {\r
3247                                         this.t入力・パラメータ食い込みチェック( "TITLE", ref strコマンド, ref strパラメータ );\r
3248                                         this.TITLE = strパラメータ;\r
3249                                 }\r
3250                                 //-----------------\r
3251                                 #endregion\r
3252                                 #region [ ARTIST ]\r
3253                                 //-----------------\r
3254                                 else if( strコマンド.StartsWith( "ARTIST", StringComparison.OrdinalIgnoreCase ) )\r
3255                                 {\r
3256                                         this.t入力・パラメータ食い込みチェック( "ARTIST", ref strコマンド, ref strパラメータ );\r
3257                                         this.ARTIST = strパラメータ;\r
3258                                 }\r
3259                                 //-----------------\r
3260                                 #endregion\r
3261                                 #region [ COMMENT ]\r
3262                                 //-----------------\r
3263                                 else if( strコマンド.StartsWith( "COMMENT", StringComparison.OrdinalIgnoreCase ) )\r
3264                                 {\r
3265                                         this.t入力・パラメータ食い込みチェック( "COMMENT", ref strコマンド, ref strパラメータ );\r
3266                                         this.COMMENT = strパラメータ;\r
3267                                 }\r
3268                                 //-----------------\r
3269                                 #endregion\r
3270                                 #region [ DLEVEL, PLAYLEVEL ]\r
3271                                 //-----------------\r
3272                                 else if(\r
3273                                         strコマンド.StartsWith( "DLEVEL", StringComparison.OrdinalIgnoreCase ) ||\r
3274                                         strコマンド.StartsWith( "PLAYLEVEL", StringComparison.OrdinalIgnoreCase ) )\r
3275                                 {\r
3276                                         this.t入力・パラメータ食い込みチェック( "DLEVEL", ref strコマンド, ref strパラメータ );\r
3277                                         this.t入力・パラメータ食い込みチェック( "PLAYLEVEL", ref strコマンド, ref strパラメータ );\r
3278 \r
3279                                         int dlevel;\r
3280                                         if( int.TryParse( strパラメータ, out dlevel ) )\r
3281                                         {\r
3282                                                 this.LEVEL.Drums = Math.Min( Math.Max( dlevel, 0 ), 100 );      // 0~100 に丸める\r
3283                                         }\r
3284                                 }\r
3285                                 //-----------------\r
3286                                 #endregion\r
3287                                 #region [ GLEVEL ]\r
3288                                 //-----------------\r
3289                                 else if( strコマンド.StartsWith( "GLEVEL", StringComparison.OrdinalIgnoreCase ) )\r
3290                                 {\r
3291                                         this.t入力・パラメータ食い込みチェック( "GLEVEL", ref strコマンド, ref strパラメータ );\r
3292 \r
3293                                         int glevel;\r
3294                                         if( int.TryParse( strパラメータ, out glevel ) )\r
3295                                         {\r
3296                                                 this.LEVEL.Guitar = Math.Min( Math.Max( glevel, 0 ), 100 );             // 0~100 に丸める\r
3297                                         }\r
3298                                 }\r
3299                                 //-----------------\r
3300                                 #endregion\r
3301                                 #region [ BLEVEL ]\r
3302                                 //-----------------\r
3303                                 else if( strコマンド.StartsWith( "BLEVEL", StringComparison.OrdinalIgnoreCase ) )\r
3304                                 {\r
3305                                         this.t入力・パラメータ食い込みチェック( "BLEVEL", ref strコマンド, ref strパラメータ );\r
3306 \r
3307                                         int blevel;\r
3308                                         if( int.TryParse( strパラメータ, out blevel ) )\r
3309                                         {\r
3310                                                 this.LEVEL.Bass = Math.Min( Math.Max( blevel, 0 ), 100 );               // 0~100 に丸める\r
3311                                         }\r
3312                                 }\r
3313                                 //-----------------\r
3314                                 #endregion\r
3315 #if TEST_NOTEOFFMODE\r
3316                                 else if (str.StartsWith("SUPRESSNOTEOFF_HIHAT", StringComparison.OrdinalIgnoreCase)) {\r
3317                                         this.t入力・パラメータ食い込みチェック("SUPRESSNOTEOFF_HIHAT", ref str, ref str2);\r
3318                                         this.bHH演奏で直前のHHを消音する = !str2.ToLower().Equals("on");\r
3319                                 } \r
3320                                 else if (str.StartsWith("SUPRESSNOTEOFF_GUITAR", StringComparison.OrdinalIgnoreCase)) {\r
3321                                         this.t入力・パラメータ食い込みチェック("SUPRESSNOTEOFF_GUITAR", ref str, ref str2);\r
3322                                         this.bGUITAR演奏で直前のGUITARを消音する = !str2.ToLower().Equals("on");\r
3323                                 }\r
3324                                 else if (str.StartsWith("SUPRESSNOTEOFF_BASS", StringComparison.OrdinalIgnoreCase)) {\r
3325                                         this.t入力・パラメータ食い込みチェック("SUPRESSNOTEOFF_BASS", ref str, ref str2);\r
3326                                         this.bBASS演奏で直前のBASSを消音する = !str2.ToLower().Equals("on");\r
3327                                 }\r
3328 #endif\r
3329                                 #region [ GENRE ]\r
3330                                 //-----------------\r
3331                                 else if( strコマンド.StartsWith( "GENRE", StringComparison.OrdinalIgnoreCase ) )\r
3332                                 {\r
3333                                         this.t入力・パラメータ食い込みチェック( "GENRE", ref strコマンド, ref strパラメータ );\r
3334                                         this.GENRE = strパラメータ;\r
3335                                 }\r
3336                                 //-----------------\r
3337                                 #endregion\r
3338                                 #region [ HIDDENLEVEL ]\r
3339                                 //-----------------\r
3340                                 else if( strコマンド.StartsWith( "HIDDENLEVEL", StringComparison.OrdinalIgnoreCase ) )\r
3341                                 {\r
3342                                         this.t入力・パラメータ食い込みチェック( "HIDDENLEVEL", ref strコマンド, ref strパラメータ );\r
3343                                         this.HIDDENLEVEL = strパラメータ.ToLower().Equals( "on" );\r
3344                                 }\r
3345                                 //-----------------\r
3346                                 #endregion\r
3347                                 #region [ STAGEFILE ]\r
3348                                 //-----------------\r
3349                                 else if( strコマンド.StartsWith( "STAGEFILE", StringComparison.OrdinalIgnoreCase ) )\r
3350                                 {\r
3351                                         this.t入力・パラメータ食い込みチェック( "STAGEFILE", ref strコマンド, ref strパラメータ );\r
3352                                         this.STAGEFILE = strパラメータ;\r
3353                                 }\r
3354                                 //-----------------\r
3355                                 #endregion\r
3356                                 #region [ PREVIEW ]\r
3357                                 //-----------------\r
3358                                 else if( strコマンド.StartsWith( "PREVIEW", StringComparison.OrdinalIgnoreCase ) )\r
3359                                 {\r
3360                                         this.t入力・パラメータ食い込みチェック( "PREVIEW", ref strコマンド, ref strパラメータ );\r
3361                                         this.PREVIEW = strパラメータ;\r
3362                                 }\r
3363                                 //-----------------\r
3364                                 #endregion\r
3365                                 #region [ PREIMAGE ]\r
3366                                 //-----------------\r
3367                                 else if( strコマンド.StartsWith( "PREIMAGE", StringComparison.OrdinalIgnoreCase ) )\r
3368                                 {\r
3369                                         this.t入力・パラメータ食い込みチェック( "PREIMAGE", ref strコマンド, ref strパラメータ );\r
3370                                         this.PREIMAGE = strパラメータ;\r
3371                                 }\r
3372                                 //-----------------\r
3373                                 #endregion\r
3374                                 #region [ PREMOVIE ]\r
3375                                 //-----------------\r
3376                                 else if( strコマンド.StartsWith( "PREMOVIE", StringComparison.OrdinalIgnoreCase ) )\r
3377                                 {\r
3378                                         this.t入力・パラメータ食い込みチェック( "PREMOVIE", ref strコマンド, ref strパラメータ );\r
3379                                         this.PREMOVIE = strパラメータ;\r
3380                                 }\r
3381                                 //-----------------\r
3382                                 #endregion\r
3383                                 #region [ BACKGROUND_GR ]\r
3384                                 //-----------------\r
3385                                 else if( strコマンド.StartsWith( "BACKGROUND_GR", StringComparison.OrdinalIgnoreCase ) )\r
3386                                 {\r
3387                                         this.t入力・パラメータ食い込みチェック( "BACKGROUND_GR", ref strコマンド, ref strパラメータ );\r
3388                                         this.BACKGROUND_GR = strパラメータ;\r
3389                                 }\r
3390                                 //-----------------\r
3391                                 #endregion\r
3392                                 #region [ BACKGROU}ND, WALL ]\r
3393                                 //-----------------\r
3394                                 else if(\r
3395                                         strコマンド.StartsWith( "BACKGROUND", StringComparison.OrdinalIgnoreCase ) ||\r
3396                                         strコマンド.StartsWith( "WALL", StringComparison.OrdinalIgnoreCase ) )\r
3397                                 {\r
3398                                         this.t入力・パラメータ食い込みチェック( "BACKGROUND", ref strコマンド, ref strパラメータ );\r
3399                                         this.t入力・パラメータ食い込みチェック( "WALL", ref strコマンド, ref strパラメータ );\r
3400                                         this.BACKGROUND = strパラメータ;\r
3401                                 }\r
3402                                 //-----------------\r
3403                                 #endregion\r
3404                                 #region [ RANDOM ]\r
3405                                 //-----------------\r
3406                                 else if( strコマンド.StartsWith( "RANDOM", StringComparison.OrdinalIgnoreCase ) )\r
3407                                 {\r
3408                                         this.t入力・パラメータ食い込みチェック( "RANDOM", ref strコマンド, ref strパラメータ );\r
3409 \r
3410                                         int n数値 = 1;\r
3411                                         if( !int.TryParse( strパラメータ, out n数値 ) )\r
3412                                                 n数値 = 1;\r
3413 \r
3414                                         this.n現在の乱数 = CDTXMania.Random.Next( n数値 ) + 1;           // 1~数値 までの乱数を生成。\r
3415                                 }\r
3416                                 //-----------------\r
3417                                 #endregion\r
3418                                 #region [ SOUND_NOWLOADING ]\r
3419                                 //-----------------\r
3420                                 else if( strコマンド.StartsWith( "SOUND_NOWLOADING", StringComparison.OrdinalIgnoreCase ) )\r
3421                                 {\r
3422                                         this.t入力・パラメータ食い込みチェック( "SOUND_NOWLOADING", ref strコマンド, ref strパラメータ );\r
3423                                         this.SOUND_NOWLOADING = strパラメータ;\r
3424                                 }\r
3425                                 //-----------------\r
3426                                 #endregion\r
3427                                 #region [ BPM ]\r
3428                                 //-----------------\r
3429                                 else if( strコマンド.StartsWith( "BPM", StringComparison.OrdinalIgnoreCase ) )\r
3430                                 {\r
3431                                         this.t入力・行解析・BPM_BPMzz( strコマンド, strパラメータ, strコメント );\r
3432                                 }\r
3433                                 //-----------------\r
3434                                 #endregion\r
3435                                 else if( !this.bヘッダのみ )               // ヘッダのみの解析の場合、以下は無視。\r
3436                                 {\r
3437                                         #region [ PANEL ]\r
3438                                         //-----------------\r
3439                                         if( strコマンド.StartsWith( "PANEL", StringComparison.OrdinalIgnoreCase ) )\r
3440                                         {\r
3441                                                 this.t入力・パラメータ食い込みチェック( "PANEL", ref strコマンド, ref strパラメータ );\r
3442 \r
3443                                                 int dummyResult;                                                                // #23885 2010.12.12 yyagi: not to confuse "#PANEL strings (panel)" and "#PANEL int (panpot of EL)"\r
3444                                                 if( !int.TryParse( strパラメータ, out dummyResult ) )\r
3445                                                 {               // 数値じゃないならPANELとみなす\r
3446                                                         this.PANEL = strパラメータ;                                                        //\r
3447                                                         goto EOL;                                                                       //\r
3448                                                 }                                                                                               // 数値ならPAN ELとみなす\r
3449 \r
3450                                         }\r
3451                                         //-----------------\r
3452                                         #endregion\r
3453                                         #region [ MIDIFILE ]\r
3454                                         //-----------------\r
3455                                         else if( strコマンド.StartsWith( "MIDIFILE", StringComparison.OrdinalIgnoreCase ) )\r
3456                                         {\r
3457                                                 this.t入力・パラメータ食い込みチェック( "MIDIFILE", ref strコマンド, ref strパラメータ );\r
3458                                                 this.MIDIFILE = strパラメータ;\r
3459                                         }\r
3460                                         //-----------------\r
3461                                         #endregion\r
3462                                         #region [ MIDINOTE ]\r
3463                                         //-----------------\r
3464                                         else if( strコマンド.StartsWith( "MIDINOTE", StringComparison.OrdinalIgnoreCase ) )\r
3465                                         {\r
3466                                                 this.t入力・パラメータ食い込みチェック( "MIDINOTE", ref strコマンド, ref strパラメータ );\r
3467                                                 this.MIDINOTE = strパラメータ.ToLower().Equals( "on" );\r
3468                                         }\r
3469                                         //-----------------\r
3470                                         #endregion\r
3471                                         #region [ BLACKCOLORKEY ]\r
3472                                         //-----------------\r
3473                                         else if( strコマンド.StartsWith( "BLACKCOLORKEY", StringComparison.OrdinalIgnoreCase ) )\r
3474                                         {\r
3475                                                 this.t入力・パラメータ食い込みチェック( "BLACKCOLORKEY", ref strコマンド, ref strパラメータ );\r
3476                                                 this.BLACKCOLORKEY = strパラメータ.ToLower().Equals( "on" );\r
3477                                         }\r
3478                                         //-----------------\r
3479                                         #endregion\r
3480                                         #region [ BASEBPM ]\r
3481                                         //-----------------\r
3482                                         else if( strコマンド.StartsWith( "BASEBPM", StringComparison.OrdinalIgnoreCase ) )\r
3483                                         {\r
3484                                                 this.t入力・パラメータ食い込みチェック( "BASEBPM", ref strコマンド, ref strパラメータ );\r
3485 \r
3486                                                 double basebpm = 0.0;\r
3487                                                 //if( double.TryParse( str2, out num6 ) && ( num6 > 0.0 ) )\r
3488                                                 if( TryParse( strパラメータ, out basebpm ) && basebpm > 0.0 )      // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point\r
3489                                                 {                                                                                                       // #24204 2011.01.21 yyagi: Fix the condition correctly\r
3490                                                         this.BASEBPM = basebpm;\r
3491                                                 }\r
3492                                         }\r
3493                                         //-----------------\r
3494                                         #endregion\r
3495                                         #region [ SOUND_STAGEFAILED ]\r
3496                                         //-----------------\r
3497                                         else if( strコマンド.StartsWith( "SOUND_STAGEFAILED", StringComparison.OrdinalIgnoreCase ) )\r
3498                                         {\r
3499                                                 this.t入力・パラメータ食い込みチェック( "SOUND_STAGEFAILED", ref strコマンド, ref strパラメータ );\r
3500                                                 this.SOUND_STAGEFAILED = strパラメータ;\r
3501                                         }\r
3502                                         //-----------------\r
3503                                         #endregion\r
3504                                         #region [ SOUND_FULLCOMBO ]\r
3505                                         //-----------------\r
3506                                         else if( strコマンド.StartsWith( "SOUND_FULLCOMBO", StringComparison.OrdinalIgnoreCase ) )\r
3507                                         {\r
3508                                                 this.t入力・パラメータ食い込みチェック( "SOUND_FULLCOMBO", ref strコマンド, ref strパラメータ );\r
3509                                                 this.SOUND_FULLCOMBO = strパラメータ;\r
3510                                         }\r
3511                                         //-----------------\r
3512                                         #endregion\r
3513                                         #region [ SOUND_AUDIENCE ]\r
3514                                         //-----------------\r
3515                                         else if( strコマンド.StartsWith( "SOUND_AUDIENCE", StringComparison.OrdinalIgnoreCase ) )\r
3516                                         {\r
3517                                                 this.t入力・パラメータ食い込みチェック( "SOUND_AUDIENCE", ref strコマンド, ref strパラメータ );\r
3518                                                 this.SOUND_AUDIENCE = strパラメータ;\r
3519                                         }\r
3520                                         //-----------------\r
3521                                         #endregion\r
3522                                         #region [ DTXVPLAYSPEED ]\r
3523                                         //-----------------\r
3524                                         else if ( strコマンド.StartsWith( "DTXVPLAYSPEED", StringComparison.OrdinalIgnoreCase ) )\r
3525                                         {\r
3526                                                 this.t入力・パラメータ食い込みチェック( "DTXVPLAYSPEED", ref strコマンド, ref strパラメータ );\r
3527 \r
3528                                                 double dtxvplayspeed = 0.0;\r
3529                                                 if ( TryParse( strパラメータ, out dtxvplayspeed ) && dtxvplayspeed > 0.0 )\r
3530                                                 {\r
3531                                                         this.dbDTXVPlaySpeed = dtxvplayspeed;\r
3532                                                 }\r
3533                                         }\r
3534                                         //-----------------\r
3535                                         #endregion\r
3536                                         // オブジェクト記述コマンドの処理。\r
3537 \r
3538                                         else if( !this.t入力・行解析・WAVVOL_VOLUME( strコマンド, strパラメータ, strコメント ) &&\r
3539                                                 !this.t入力・行解析・WAVPAN_PAN( strコマンド, strパラメータ, strコメント ) &&\r
3540                                                 !this.t入力・行解析・WAV( strコマンド, strパラメータ, strコメント ) &&\r
3541                                                 !this.t入力・行解析・BMPTEX( strコマンド, strパラメータ, strコメント ) &&\r
3542                                                 !this.t入力・行解析・BMP( strコマンド, strパラメータ, strコメント ) &&\r
3543                                                 !this.t入力・行解析・BGAPAN( strコマンド, strパラメータ, strコメント ) &&\r
3544                                                 !this.t入力・行解析・BGA( strコマンド, strパラメータ, strコメント ) &&\r
3545                                                 !this.t入力・行解析・AVIPAN( strコマンド, strパラメータ, strコメント ) &&\r
3546                                                 !this.t入力・行解析・AVI_VIDEO( strコマンド, strパラメータ, strコメント ) &&\r
3547                                         //      !this.t入力・行解析・BPM_BPMzz( strコマンド, strパラメータ, strコメント ) &&        // bヘッダのみ==trueの場合でもチェックするよう変更\r
3548                                                 !this.t入力・行解析・RESULTIMAGE( strコマンド, strパラメータ, strコメント ) &&\r
3549                                                 !this.t入力・行解析・RESULTMOVIE( strコマンド, strパラメータ, strコメント ) &&\r
3550                                                 !this.t入力・行解析・RESULTSOUND( strコマンド, strパラメータ, strコメント ) &&\r
3551                                                 !this.t入力・行解析・SIZE( strコマンド, strパラメータ, strコメント ) )\r
3552                                         {\r
3553                                                 this.t入力・行解析・チップ配置( strコマンド, strパラメータ, strコメント );\r
3554                                         }\r
3555                                 EOL:\r
3556                                         Debug.Assert( true );           // #23885 2010.12.12 yyagi: dummy line to exit parsing the line\r
3557                                                                                                 // 2011.8.17 from: "int xx=0;" から変更。毎回警告が出るので。\r
3558                                 }\r
3559                                 //else\r
3560                                 //{     // Duration測定のため、bヘッダのみ==trueでも、チップ配置は行う\r
3561                                 //      this.t入力・行解析・チップ配置( strコマンド, strパラメータ, strコメント );\r
3562                                 //}\r
3563                         }\r
3564                 }\r
3565                 private bool t入力・行解析・AVI_VIDEO( string strコマンド, string strパラメータ, string strコメント )\r
3566                 {\r
3567                         // (1) コマンドを処理。\r
3568 \r
3569                         #region [ "AVI" or "VIDEO" で始まらないコマンドは無効。]\r
3570                         //-----------------\r
3571                         if( strコマンド.StartsWith( "AVI", StringComparison.OrdinalIgnoreCase ) )\r
3572                                 strコマンド = strコマンド.Substring( 3 );               // strコマンド から先頭の"AVI"文字を除去。\r
3573 \r
3574                         else if( strコマンド.StartsWith( "VIDEO", StringComparison.OrdinalIgnoreCase ) )\r
3575                                 strコマンド = strコマンド.Substring( 5 );               // strコマンド から先頭の"VIDEO"文字を除去。\r
3576 \r
3577                         else\r
3578                                 return false;\r
3579                         //-----------------\r
3580                         #endregion\r
3581 \r
3582                         // (2) パラメータを処理。\r
3583 \r
3584                         if( strコマンド.Length < 2 )\r
3585                                 return false;   // AVI番号 zz がないなら無効。\r
3586 \r
3587                         #region [ AVI番号 zz を取得する。]\r
3588                         //-----------------\r
3589                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
3590                         if( zz < 0 || zz >= 36 * 36 )\r
3591                         {\r
3592                                 Trace.TraceError( "AVI(VIDEO)番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
3593                                 return false;\r
3594                         }\r
3595                         //-----------------\r
3596                         #endregion\r
3597 \r
3598                         #region [ AVIリストに {zz, avi} の組を登録する。 ]\r
3599                         //-----------------\r
3600                         var avi = new CAVI() {\r
3601                                 n番号 = zz,\r
3602                                 strファイル名 = strパラメータ,\r
3603                                 strコメント文 = strコメント,\r
3604                         };\r
3605 \r
3606                         if( this.listAVI.ContainsKey( zz ) )    // 既にリスト中に存在しているなら削除。後のものが有効。\r
3607                                 this.listAVI.Remove( zz );\r
3608 \r
3609                         this.listAVI.Add( zz, avi );\r
3610                         //-----------------\r
3611                         #endregion\r
3612 \r
3613                         return true;\r
3614                 }\r
3615                 private bool t入力・行解析・AVIPAN( string strコマンド, string strパラメータ, string strコメント )\r
3616                 {\r
3617                         // (1) コマンドを処理。\r
3618 \r
3619                         #region [ "AVIPAN" で始まらないコマンドは無効。]\r
3620                         //-----------------\r
3621                         if( !strコマンド.StartsWith( "AVIPAN", StringComparison.OrdinalIgnoreCase ) )\r
3622                                 return false;\r
3623 \r
3624                         strコマンド = strコマンド.Substring( 6 );       // strコマンド から先頭の"AVIPAN"文字を除去。\r
3625                         //-----------------\r
3626                         #endregion\r
3627 \r
3628                         // (2) パラメータを処理。\r
3629 \r
3630                         if( strコマンド.Length < 2 )\r
3631                                 return false;   // AVIPAN番号 zz がないなら無効。\r
3632 \r
3633                         #region [ AVIPAN番号 zz を取得する。]\r
3634                         //-----------------\r
3635                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
3636                         if( zz < 0 || zz >= 36 * 36 )\r
3637                         {\r
3638                                 Trace.TraceError( "AVIPAN番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
3639                                 return false;\r
3640                         }\r
3641                         //-----------------\r
3642                         #endregion\r
3643 \r
3644                         var avipan = new CAVIPAN() {\r
3645                                 n番号 = zz,\r
3646                         };\r
3647 \r
3648                         // パラメータ引数(14個)を取得し、avipan に登録していく。\r
3649 \r
3650                         string[] strParams = strパラメータ.Split( new char[] { ' ', ',', '(', ')', '[', ']', 'x', '|' }, StringSplitOptions.RemoveEmptyEntries );\r
3651 \r
3652                         #region [ パラメータ引数は全14個ないと無効。]\r
3653                         //-----------------\r
3654                         if( strParams.Length < 14 )\r
3655                         {\r
3656                                 Trace.TraceError( "AVIPAN: 引数が足りません。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
3657                                 return false;\r
3658                         }\r
3659                         //-----------------\r
3660                         #endregion\r
3661 \r
3662                         int i = 0;\r
3663                         int n値 = 0;\r
3664 \r
3665                         #region [ 1. AVI番号 ]\r
3666                         //-----------------\r
3667                         if( string.IsNullOrEmpty( strParams[ i ] ) || strParams[ i ].Length > 2 )\r
3668                         {\r
3669                                 Trace.TraceError( "AVIPAN: {2}番目の数(AVI番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3670                                 return false;\r
3671                         }\r
3672                         avipan.nAVI番号 = C変換.n36進数2桁の文字列を数値に変換して返す( strParams[ i ] );\r
3673                         if( avipan.nAVI番号 < 1 || avipan.nAVI番号 >= 36 * 36 )\r
3674                         {\r
3675                                 Trace.TraceError( "AVIPAN: {2}番目の数(AVI番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3676                                 return false;\r
3677                         }\r
3678                         i++;\r
3679                         //-----------------\r
3680                         #endregion\r
3681                         #region [ 2. 開始転送サイズ・幅 ]\r
3682                         //-----------------\r
3683                         n値 = 0;\r
3684                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3685                         {\r
3686                                 Trace.TraceError( "AVIPAN: {2}番目の引数(開始転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3687                                 return false;\r
3688                         }\r
3689                         avipan.sz開始サイズ.Width = n値;\r
3690                         i++;\r
3691                         //-----------------\r
3692                         #endregion\r
3693                         #region [ 3. 転送サイズ・高さ ]\r
3694                         //-----------------\r
3695                         n値 = 0;\r
3696                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3697                         {\r
3698                                 Trace.TraceError( "AVIPAN: {2}番目の引数(開始転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3699                                 return false;\r
3700                         }\r
3701                         avipan.sz開始サイズ.Height = n値;\r
3702                         i++;\r
3703                         //-----------------\r
3704                         #endregion\r
3705                         #region [ 4. 終了転送サイズ・幅 ]\r
3706                         //-----------------\r
3707                         n値 = 0;\r
3708                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3709                         {\r
3710                                 Trace.TraceError( "AVIPAN: {2}番目の引数(終了転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3711                                 return false;\r
3712                         }\r
3713                         avipan.sz終了サイズ.Width = n値;\r
3714                         i++;\r
3715                         //-----------------\r
3716                         #endregion\r
3717                         #region [ 5. 終了転送サイズ・高さ ]\r
3718                         //-----------------\r
3719                         n値 = 0;\r
3720                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3721                         {\r
3722                                 Trace.TraceError( "AVIPAN: {2}番目の引数(終了転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3723                                 return false;\r
3724                         }\r
3725                         avipan.sz終了サイズ.Height = n値;\r
3726                         i++;\r
3727                         //-----------------\r
3728                         #endregion\r
3729                         #region [ 6. 動画側開始位置・X ]\r
3730                         //-----------------\r
3731                         n値 = 0;\r
3732                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3733                         {\r
3734                                 Trace.TraceError( "AVIPAN: {2}番目の引数(動画側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3735                                 return false;\r
3736                         }\r
3737                         avipan.pt動画側開始位置.X = n値;\r
3738                         i++;\r
3739                         //-----------------\r
3740                         #endregion\r
3741                         #region [ 7. 動画側開始位置・Y ]\r
3742                         //-----------------\r
3743                         n値 = 0;\r
3744                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3745                         {\r
3746                                 Trace.TraceError( "AVIPAN: {2}番目の引数(動画側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3747                                 return false;\r
3748                         }\r
3749                         avipan.pt動画側開始位置.Y = n値;\r
3750                         i++;\r
3751                         //-----------------\r
3752                         #endregion\r
3753                         #region [ 8. 動画側終了位置・X ]\r
3754                         //-----------------\r
3755                         n値 = 0;\r
3756                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3757                         {\r
3758                                 Trace.TraceError( "AVIPAN: {2}番目の引数(動画側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3759                                 return false;\r
3760                         }\r
3761                         avipan.pt動画側終了位置.X = n値;\r
3762                         i++;\r
3763                         //-----------------\r
3764                         #endregion\r
3765                         #region [ 9. 動画側終了位置・Y ]\r
3766                         //-----------------\r
3767                         n値 = 0;\r
3768                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3769                         {\r
3770                                 Trace.TraceError( "AVIPAN: {2}番目の引数(動画側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3771                                 return false;\r
3772                         }\r
3773                         avipan.pt動画側終了位置.Y = n値;\r
3774                         i++;\r
3775                         //-----------------\r
3776                         #endregion\r
3777                         #region [ 10.表示側開始位置・X ]\r
3778                         //-----------------\r
3779                         n値 = 0;\r
3780                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3781                         {\r
3782                                 Trace.TraceError( "AVIPAN: {2}番目の引数(表示側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3783                                 return false;\r
3784                         }\r
3785                         avipan.pt表示側開始位置.X = n値;\r
3786                         i++;\r
3787                         //-----------------\r
3788                         #endregion\r
3789                         #region [ 11.表示側開始位置・Y ]\r
3790                         //-----------------\r
3791                         n値 = 0;\r
3792                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3793                         {\r
3794                                 Trace.TraceError( "AVIPAN: {2}番目の引数(表示側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3795                                 return false;\r
3796                         }\r
3797                         avipan.pt表示側開始位置.Y = n値;\r
3798                         i++;\r
3799                         //-----------------\r
3800                         #endregion\r
3801                         #region [ 12.表示側終了位置・X ]\r
3802                         //-----------------\r
3803                         n値 = 0;\r
3804                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3805                         {\r
3806                                 Trace.TraceError( "AVIPAN: {2}番目の引数(表示側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3807                                 return false;\r
3808                         }\r
3809                         avipan.pt表示側終了位置.X = n値;\r
3810                         i++;\r
3811                         //-----------------\r
3812                         #endregion\r
3813                         #region [ 13.表示側終了位置・Y ]\r
3814                         //-----------------\r
3815                         n値 = 0;\r
3816                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3817                         {\r
3818                                 Trace.TraceError( "AVIPAN: {2}番目の引数(表示側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3819                                 return false;\r
3820                         }\r
3821                         avipan.pt表示側終了位置.Y = n値;\r
3822                         i++;\r
3823                         //-----------------\r
3824                         #endregion\r
3825                         #region [ 14.移動時間 ]\r
3826                         //-----------------\r
3827                         n値 = 0;\r
3828                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3829                         {\r
3830                                 Trace.TraceError( "AVIPAN: {2}番目の引数(移動時間)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3831                                 return false;\r
3832                         }\r
3833 \r
3834                         if( n値 < 0 )\r
3835                                 n値 = 0;\r
3836 \r
3837                         avipan.n移動時間ct = n値;\r
3838                         i++;\r
3839                         //-----------------\r
3840                         #endregion\r
3841 \r
3842                         #region [ AVIPANリストに {zz, avipan} の組を登録する。]\r
3843                         //-----------------\r
3844                         if( this.listAVIPAN.ContainsKey( zz ) ) // 既にリスト中に存在しているなら削除。後のものが有効。\r
3845                                 this.listAVIPAN.Remove( zz );\r
3846 \r
3847                         this.listAVIPAN.Add( zz, avipan );\r
3848                         //-----------------\r
3849                         #endregion\r
3850 \r
3851                         return true;\r
3852                 }\r
3853                 private bool t入力・行解析・BGA( string strコマンド, string strパラメータ, string strコメント )\r
3854                 {\r
3855                         // (1) コマンドを処理。\r
3856 \r
3857                         #region [ "BGA" で始まらないコマンドは無効。]\r
3858                         //-----------------\r
3859                         if( !strコマンド.StartsWith( "BGA", StringComparison.OrdinalIgnoreCase ) )\r
3860                                 return false;\r
3861 \r
3862                         strコマンド = strコマンド.Substring( 3 );       // strコマンド から先頭の"BGA"文字を除去。\r
3863                         //-----------------\r
3864                         #endregion\r
3865 \r
3866                         // (2) パラメータを処理。\r
3867 \r
3868                         if( strコマンド.Length < 2 )\r
3869                                 return false;   // BGA番号 zz がないなら無効。\r
3870 \r
3871                         #region [ BGA番号 zz を取得する。]\r
3872                         //-----------------\r
3873                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
3874                         if( zz < 0 || zz >= 36 * 36 )\r
3875                         {\r
3876                                 Trace.TraceError( "BGA番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
3877                                 return false;\r
3878                         }\r
3879                         //-----------------\r
3880                         #endregion\r
3881 \r
3882                         var bga = new CBGA() {\r
3883                                 n番号 = zz,\r
3884                         };\r
3885 \r
3886                         // パラメータ引数(7個)を取得し、bga に登録していく。\r
3887 \r
3888                         string[] strParams = strパラメータ.Split( new char[] { ' ', ',', '(', ')', '[', ']', 'x', '|' }, StringSplitOptions.RemoveEmptyEntries );\r
3889 \r
3890                         #region [ パラメータ引数は全7個ないと無効。]\r
3891                         //-----------------\r
3892                         if( strParams.Length < 7 )\r
3893                         {\r
3894                                 Trace.TraceError( "BGA: 引数が足りません。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
3895                                 return false;\r
3896                         }\r
3897                         //-----------------\r
3898                         #endregion\r
3899 \r
3900                         int i = 0;\r
3901                         int n値 = 0;\r
3902 \r
3903                         #region [ 1.BMP番号 ]\r
3904                         //-----------------\r
3905                         if( string.IsNullOrEmpty( strParams[ i ] ) || strParams[ i ].Length > 2 )\r
3906                         {\r
3907                                 Trace.TraceError( "BGA: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3908                                 return false;\r
3909                         }\r
3910                         bga.nBMP番号 = C変換.n36進数2桁の文字列を数値に変換して返す( strParams[ i ] );\r
3911                         if( bga.nBMP番号 < 1 || bga.nBMP番号 >= 36 * 36 )\r
3912                         {\r
3913                                 Trace.TraceError( "BGA: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3914                                 return false;\r
3915                         }\r
3916                         i++;\r
3917                         //-----------------\r
3918                         #endregion\r
3919                         #region [ 2.画像側位置1・X ]\r
3920                         //-----------------\r
3921                         n値 = 0;\r
3922                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3923                         {\r
3924                                 Trace.TraceError( "BGA: {2}番目の引数(画像側位置1・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3925                                 return false;\r
3926                         }\r
3927                         bga.pt画像側左上座標.X = n値;\r
3928                         i++;\r
3929                         //-----------------\r
3930                         #endregion\r
3931                         #region [ 3.画像側位置1・Y ]\r
3932                         //-----------------\r
3933                         n値 = 0;\r
3934                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3935                         {\r
3936                                 Trace.TraceError( "BGA: {2}番目の引数(画像側位置1・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3937                                 return false;\r
3938                         }\r
3939                         bga.pt画像側左上座標.Y = n値;\r
3940                         i++;\r
3941                         //-----------------\r
3942                         #endregion\r
3943                         #region [ 4.画像側位置2・X ]\r
3944                         //-----------------\r
3945                         n値 = 0;\r
3946                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3947                         {\r
3948                                 Trace.TraceError( "BGA: {2}番目の引数(画像側位置2・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3949                                 return false;\r
3950                         }\r
3951                         bga.pt画像側右下座標.X = n値;\r
3952                         i++;\r
3953                         //-----------------\r
3954                         #endregion\r
3955                         #region [ 5.画像側位置2・Y ]\r
3956                         //-----------------\r
3957                         n値 = 0;\r
3958                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3959                         {\r
3960                                 Trace.TraceError( "BGA: {2}番目の引数(画像側座標2・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3961                                 return false;\r
3962                         }\r
3963                         bga.pt画像側右下座標.Y = n値;\r
3964                         i++;\r
3965                         //-----------------\r
3966                         #endregion\r
3967                         #region [ 6.表示位置・X ]\r
3968                         //-----------------\r
3969                         n値 = 0;\r
3970                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3971                         {\r
3972                                 Trace.TraceError( "BGA: {2}番目の引数(表示位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3973                                 return false;\r
3974                         }\r
3975                         bga.pt表示座標.X = n値;\r
3976                         i++;\r
3977                         //-----------------\r
3978                         #endregion\r
3979                         #region [ 7.表示位置・Y ]\r
3980                         //-----------------\r
3981                         n値 = 0;\r
3982                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
3983                         {\r
3984                                 Trace.TraceError( "BGA: {2}番目の引数(表示位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
3985                                 return false;\r
3986                         }\r
3987                         bga.pt表示座標.Y = n値;\r
3988                         i++;\r
3989                         //-----------------\r
3990                         #endregion\r
3991 \r
3992                         #region [ 画像側座標の正規化とクリッピング。]\r
3993                         //-----------------\r
3994                         if( bga.pt画像側左上座標.X > bga.pt画像側右下座標.X )\r
3995                         {\r
3996                                 n値 = bga.pt画像側左上座標.X;\r
3997                                 bga.pt画像側左上座標.X = bga.pt画像側右下座標.X;\r
3998                                 bga.pt画像側右下座標.X = n値;\r
3999                         }\r
4000                         if( bga.pt画像側左上座標.Y > bga.pt画像側右下座標.Y )\r
4001                         {\r
4002                                 n値 = bga.pt画像側左上座標.Y;\r
4003                                 bga.pt画像側左上座標.Y = bga.pt画像側右下座標.Y;\r
4004                                 bga.pt画像側右下座標.Y = n値;\r
4005                         }\r
4006                         //-----------------\r
4007                         #endregion\r
4008                         #region [ BGAリストに {zz, bga} の組を登録する。]\r
4009                         //-----------------\r
4010                         if( this.listBGA.ContainsKey( zz ) )    // 既にリスト中に存在しているなら削除。後のものが有効。\r
4011                                 this.listBGA.Remove( zz );\r
4012 \r
4013                         this.listBGA.Add( zz, bga );\r
4014                         //-----------------\r
4015                         #endregion\r
4016 \r
4017                         return true;\r
4018                 }\r
4019                 private bool t入力・行解析・BGAPAN( string strコマンド, string strパラメータ, string strコメント )\r
4020                 {\r
4021                         // (1) コマンドを処理。\r
4022 \r
4023                         #region [ "BGAPAN" で始まらないコマンドは無効。]\r
4024                         //-----------------\r
4025                         if( !strコマンド.StartsWith( "BGAPAN", StringComparison.OrdinalIgnoreCase ) )\r
4026                                 return false;\r
4027 \r
4028                         strコマンド = strコマンド.Substring( 6 );       // strコマンド から先頭の"BGAPAN"文字を除去。\r
4029                         //-----------------\r
4030                         #endregion\r
4031 \r
4032                         // (2) パラメータを処理。\r
4033 \r
4034                         if( strコマンド.Length < 2 )\r
4035                                 return false;   // BGAPAN番号 zz がないなら無効。\r
4036 \r
4037                         #region [ BGAPAN番号 zz を取得する。]\r
4038                         //-----------------\r
4039                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4040                         if( zz < 0 || zz >= 36 * 36 )\r
4041                         {\r
4042                                 Trace.TraceError( "BGAPAN番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4043                                 return false;\r
4044                         }\r
4045                         //-----------------\r
4046                         #endregion\r
4047 \r
4048                         var bgapan = new CBGAPAN() {\r
4049                                 n番号 = zz,\r
4050                         };\r
4051 \r
4052                         // パラメータ引数(14個)を取得し、bgapan に登録していく。\r
4053 \r
4054                         string[] strParams = strパラメータ.Split( new char[] { ' ', ',', '(', ')', '[', ']', 'x', '|' }, StringSplitOptions.RemoveEmptyEntries );\r
4055 \r
4056                         #region [ パラメータ引数は全14個ないと無効。]\r
4057                         //-----------------\r
4058                         if( strParams.Length < 14 )\r
4059                         {\r
4060                                 Trace.TraceError( "BGAPAN: 引数が足りません。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4061                                 return false;\r
4062                         }\r
4063                         //-----------------\r
4064                         #endregion\r
4065 \r
4066                         int i = 0;\r
4067                         int n値 = 0;\r
4068 \r
4069                         #region [ 1. BMP番号 ]\r
4070                         //-----------------\r
4071                         if( string.IsNullOrEmpty( strParams[ i ] ) || strParams[ i ].Length > 2 )\r
4072                         {\r
4073                                 Trace.TraceError( "BGAPAN: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4074                                 return false;\r
4075                         }\r
4076                         bgapan.nBMP番号 = C変換.n36進数2桁の文字列を数値に変換して返す( strParams[ i ] );\r
4077                         if( bgapan.nBMP番号 < 1 || bgapan.nBMP番号 >= 36 * 36 )\r
4078                         {\r
4079                                 Trace.TraceError( "BGAPAN: {2}番目の数(BMP番号)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4080                                 return false;\r
4081                         }\r
4082                         i++;\r
4083                         //-----------------\r
4084                         #endregion\r
4085                         #region [ 2. 開始転送サイズ・幅 ]\r
4086                         //-----------------\r
4087                         n値 = 0;\r
4088                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4089                         {\r
4090                                 Trace.TraceError( "BGAPAN: {2}番目の引数(開始転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4091                                 return false;\r
4092                         }\r
4093                         bgapan.sz開始サイズ.Width = n値;\r
4094                         i++;\r
4095                         //-----------------\r
4096                         #endregion\r
4097                         #region [ 3. 開始転送サイズ・高さ ]\r
4098                         //-----------------\r
4099                         n値 = 0;\r
4100                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4101                         {\r
4102                                 Trace.TraceError( "BGAPAN: {2}番目の引数(開始転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4103                                 return false;\r
4104                         }\r
4105                         bgapan.sz開始サイズ.Height = n値;\r
4106                         i++;\r
4107                         //-----------------\r
4108                         #endregion\r
4109                         #region [ 4. 終了転送サイズ・幅 ]\r
4110                         //-----------------\r
4111                         n値 = 0;\r
4112                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4113                         {\r
4114                                 Trace.TraceError( "BGAPAN: {2}番目の引数(終了転送サイズ・幅)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4115                                 return false;\r
4116                         }\r
4117                         bgapan.sz終了サイズ.Width = n値;\r
4118                         i++;\r
4119                         //-----------------\r
4120                         #endregion\r
4121                         #region [ 5. 終了転送サイズ・高さ ]\r
4122                         //-----------------\r
4123                         n値 = 0;\r
4124                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4125                         {\r
4126                                 Trace.TraceError( "BGAPAN: {2}番目の引数(終了転送サイズ・高さ)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4127                                 return false;\r
4128                         }\r
4129                         bgapan.sz終了サイズ.Height = n値;\r
4130                         i++;\r
4131                         //-----------------\r
4132                         #endregion\r
4133                         #region [ 6. 画像側開始位置・X ]\r
4134                         //-----------------\r
4135                         n値 = 0;\r
4136                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4137                         {\r
4138                                 Trace.TraceError( "BGAPAN: {2}番目の引数(画像側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4139                                 return false;\r
4140                         }\r
4141                         bgapan.pt画像側開始位置.X = n値;\r
4142                         i++;\r
4143                         //-----------------\r
4144                         #endregion\r
4145                         #region [ 7. 画像側開始位置・Y ]\r
4146                         //-----------------\r
4147                         n値 = 0;\r
4148                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4149                         {\r
4150                                 Trace.TraceError( "BGAPAN: {2}番目の引数(画像側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4151                                 return false;\r
4152                         }\r
4153                         bgapan.pt画像側開始位置.Y = n値;\r
4154                         i++;\r
4155                         //-----------------\r
4156                         #endregion\r
4157                         #region [ 8. 画像側終了位置・X ]\r
4158                         //-----------------\r
4159                         n値 = 0;\r
4160                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4161                         {\r
4162                                 Trace.TraceError( "BGAPAN: {2}番目の引数(画像側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4163                                 return false;\r
4164                         }\r
4165                         bgapan.pt画像側終了位置.X = n値;\r
4166                         i++;\r
4167                         //-----------------\r
4168                         #endregion\r
4169                         #region [ 9. 画像側終了位置・Y ]\r
4170                         //-----------------\r
4171                         n値 = 0;\r
4172                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4173                         {\r
4174                                 Trace.TraceError( "BGAPAN: {2}番目の引数(画像側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4175                                 return false;\r
4176                         }\r
4177                         bgapan.pt画像側終了位置.Y = n値;\r
4178                         i++;\r
4179                         //-----------------\r
4180                         #endregion\r
4181                         #region [ 10.表示側開始位置・X ]\r
4182                         //-----------------\r
4183                         n値 = 0;\r
4184                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4185                         {\r
4186                                 Trace.TraceError( "BGAPAN: {2}番目の引数(表示側開始位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4187                                 return false;\r
4188                         }\r
4189                         bgapan.pt表示側開始位置.X = n値;\r
4190                         i++;\r
4191                         //-----------------\r
4192                         #endregion\r
4193                         #region [ 11.表示側開始位置・Y ]\r
4194                         //-----------------\r
4195                         n値 = 0;\r
4196                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4197                         {\r
4198                                 Trace.TraceError( "BGAPAN: {2}番目の引数(表示側開始位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4199                                 return false;\r
4200                         }\r
4201                         bgapan.pt表示側開始位置.Y = n値;\r
4202                         i++;\r
4203                         //-----------------\r
4204                         #endregion\r
4205                         #region [ 12.表示側終了位置・X ]\r
4206                         //-----------------\r
4207                         n値 = 0;\r
4208                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4209                         {\r
4210                                 Trace.TraceError( "BGAPAN: {2}番目の引数(表示側終了位置・X)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4211                                 return false;\r
4212                         }\r
4213                         bgapan.pt表示側終了位置.X = n値;\r
4214                         i++;\r
4215                         //-----------------\r
4216                         #endregion\r
4217                         #region [ 13.表示側終了位置・Y ]\r
4218                         //-----------------\r
4219                         n値 = 0;\r
4220                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4221                         {\r
4222                                 Trace.TraceError( "BGAPAN: {2}番目の引数(表示側終了位置・Y)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4223                                 return false;\r
4224                         }\r
4225                         bgapan.pt表示側終了位置.Y = n値;\r
4226                         i++;\r
4227                         //-----------------\r
4228                         #endregion\r
4229                         #region [ 14.移動時間 ]\r
4230                         //-----------------\r
4231                         n値 = 0;\r
4232                         if( !int.TryParse( strParams[ i ], out n値 ) )\r
4233                         {\r
4234                                 Trace.TraceError( "BGAPAN: {2}番目の引数(移動時間)が異常です。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数, i + 1 );\r
4235                                 return false;\r
4236                         }\r
4237 \r
4238                         if( n値 < 0 )\r
4239                                 n値 = 0;\r
4240 \r
4241                         bgapan.n移動時間ct = n値;\r
4242                         i++;\r
4243                         //-----------------\r
4244                         #endregion\r
4245 \r
4246                         #region [ BGAPANリストに {zz, bgapan} の組を登録する。]\r
4247                         //-----------------\r
4248                         if( this.listBGAPAN.ContainsKey( zz ) ) // 既にリスト中に存在しているなら削除。後のものが有効。\r
4249                                 this.listBGAPAN.Remove( zz );\r
4250 \r
4251                         this.listBGAPAN.Add( zz, bgapan );\r
4252                         //-----------------\r
4253                         #endregion\r
4254 \r
4255                         return true;\r
4256                 }\r
4257                 private bool t入力・行解析・BMP( string strコマンド, string strパラメータ, string strコメント )\r
4258                 {\r
4259                         // (1) コマンドを処理。\r
4260 \r
4261                         #region [ "BMP" で始まらないコマンドは無効。]\r
4262                         //-----------------\r
4263                         if( !strコマンド.StartsWith( "BMP", StringComparison.OrdinalIgnoreCase ) )\r
4264                                 return false;\r
4265 \r
4266                         strコマンド = strコマンド.Substring( 3 );       // strコマンド から先頭の"BMP"文字を除去。\r
4267                         //-----------------\r
4268                         #endregion\r
4269 \r
4270                         // (2) パラメータを処理。\r
4271 \r
4272                         int zz = 0;\r
4273 \r
4274                         #region [ BMP番号 zz を取得する。]\r
4275                         //-----------------\r
4276                         if( strコマンド.Length < 2 )\r
4277                         {\r
4278                                 #region [ (A) "#BMP:" の場合 → zz = 00 ]\r
4279                                 //-----------------\r
4280                                 zz = 0;\r
4281                                 //-----------------\r
4282                                 #endregion\r
4283                         }\r
4284                         else\r
4285                         {\r
4286                                 #region [ (B) "#BMPzz:" の場合 → zz = 00 ~ ZZ ]\r
4287                                 //-----------------\r
4288                                 zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4289                                 if( zz < 0 || zz >= 36 * 36 )\r
4290                                 {\r
4291                                         Trace.TraceError( "BMP番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4292                                         return false;\r
4293                                 }\r
4294                                 //-----------------\r
4295                                 #endregion\r
4296                         }\r
4297                         //-----------------\r
4298                         #endregion\r
4299 \r
4300 \r
4301                         var bmp = new CBMP() {\r
4302                                 n番号 = zz,\r
4303                                 strファイル名 = strパラメータ,\r
4304                                 strコメント文 = strコメント,\r
4305                         };\r
4306 \r
4307                         #region [ BMPリストに {zz, bmp} の組を登録。]\r
4308                         //-----------------\r
4309                         if( this.listBMP.ContainsKey( zz ) )    // 既にリスト中に存在しているなら削除。後のものが有効。\r
4310                                 this.listBMP.Remove( zz );\r
4311 \r
4312                         this.listBMP.Add( zz, bmp );\r
4313                         //-----------------\r
4314                         #endregion\r
4315 \r
4316                         return true;\r
4317                 }\r
4318                 private bool t入力・行解析・BMPTEX( string strコマンド, string strパラメータ, string strコメント )\r
4319                 {\r
4320                         // (1) コマンドを処理。\r
4321 \r
4322                         #region [ "BMPTEX" で始まらないコマンドは無効。]\r
4323                         //-----------------\r
4324                         if( !strコマンド.StartsWith( "BMPTEX", StringComparison.OrdinalIgnoreCase ) )\r
4325                                 return false;\r
4326 \r
4327                         strコマンド = strコマンド.Substring( 6 );       // strコマンド から先頭の"BMPTEX"文字を除去。\r
4328                         //-----------------\r
4329                         #endregion\r
4330 \r
4331                         // (2) パラメータを処理。\r
4332 \r
4333                         if( strコマンド.Length < 2 )\r
4334                                 return false;   // BMPTEX番号 zz がないなら無効。\r
4335 \r
4336                         #region [ BMPTEX番号 zz を取得する。]\r
4337                         //-----------------\r
4338                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4339                         if( zz < 0 || zz >= 36 * 36 )\r
4340                         {\r
4341                                 Trace.TraceError( "BMPTEX番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4342                                 return false;\r
4343                         }\r
4344                         //-----------------\r
4345                         #endregion\r
4346 \r
4347                         var bmptex = new CBMPTEX() {\r
4348                                 n番号 = zz,\r
4349                                 strファイル名 = strパラメータ,\r
4350                                 strコメント文 = strコメント,\r
4351                         };\r
4352 \r
4353                         #region [ BMPTEXリストに {zz, bmptex} の組を登録する。]\r
4354                         //-----------------\r
4355                         if( this.listBMPTEX.ContainsKey( zz ) ) // 既にリスト中に存在しているなら削除。後のものが有効。\r
4356                                 this.listBMPTEX.Remove( zz );\r
4357 \r
4358                         this.listBMPTEX.Add( zz, bmptex );\r
4359                         //-----------------\r
4360                         #endregion\r
4361 \r
4362                         return true;\r
4363                 }\r
4364                 private bool t入力・行解析・BPM_BPMzz( string strコマンド, string strパラメータ, string strコメント )\r
4365                 {\r
4366                         // (1) コマンドを処理。\r
4367 \r
4368                         #region [ "BPM" で始まらないコマンドは無効。]\r
4369                         //-----------------\r
4370                         if( !strコマンド.StartsWith( "BPM", StringComparison.OrdinalIgnoreCase ) )\r
4371                                 return false;\r
4372 \r
4373                         strコマンド = strコマンド.Substring( 3 );       // strコマンド から先頭の"BPM"文字を除去。\r
4374                         //-----------------\r
4375                         #endregion\r
4376 \r
4377                         // (2) パラメータを処理。\r
4378 \r
4379                         int zz = 0;\r
4380 \r
4381                         #region [ BPM番号 zz を取得する。]\r
4382                         //-----------------\r
4383                         if( strコマンド.Length < 2 )\r
4384                         {\r
4385                                 #region [ (A) "#BPM:" の場合 → zz = 00 ]\r
4386                                 //-----------------\r
4387                                 zz = 0;\r
4388                                 //-----------------\r
4389                                 #endregion\r
4390                         }\r
4391                         else\r
4392                         {\r
4393                                 #region [ (B) "#BPMzz:" の場合 → zz = 00 ~ ZZ ]\r
4394                                 //-----------------\r
4395                                 zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4396                                 if( zz < 0 || zz >= 36 * 36 )\r
4397                                 {\r
4398                                         Trace.TraceError( "BPM番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4399                                         return false;\r
4400                                 }\r
4401                                 //-----------------\r
4402                                 #endregion\r
4403                         }\r
4404                         //-----------------\r
4405                         #endregion\r
4406 \r
4407                         double dbBPM = 0.0;\r
4408 \r
4409                         #region [ BPM値を取得する。]\r
4410                         //-----------------\r
4411                         //if( !double.TryParse( strパラメータ, out result ) )\r
4412                         if( !TryParse( strパラメータ, out dbBPM ) )                        // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point\r
4413                                 return false;\r
4414 \r
4415                         if( dbBPM <= 0.0 )\r
4416                                 return false;\r
4417                         //-----------------\r
4418                         #endregion\r
4419 \r
4420                         if( zz == 0 )                   // "#BPM00:" と "#BPM:" は等価。\r
4421                                 this.BPM = dbBPM;       // この曲の代表 BPM に格納する。\r
4422 \r
4423                         #region [ BPMリストに {内部番号, zz, dbBPM} の組を登録。]\r
4424                         //-----------------\r
4425                         this.listBPM.Add(\r
4426                                 this.n内部番号BPM1to,\r
4427                                 new CBPM() {\r
4428                                         n内部番号 = this.n内部番号BPM1to,\r
4429                                         n表記上の番号 = zz,\r
4430                                         dbBPM値 = dbBPM,\r
4431                                 } );\r
4432                         //-----------------\r
4433                         #endregion\r
4434 \r
4435                         #region [ BPM番号が zz であるBPM未設定のBPMチップがあれば、そのサイズを変更する。無限管理に対応。]\r
4436                         //-----------------\r
4437                         if( this.n無限管理BPM[ zz ] == -zz )        // 初期状態では n無限管理BPM[zz] = -zz である。この場合、#BPMzz がまだ出現していないことを意味する。\r
4438                         {\r
4439                                 for( int i = 0; i < this.listChip.Count; i++ )  // これまでに出てきたチップのうち、該当する(BPM値が未設定の)BPMチップの値を変更する(仕組み上、必ず後方参照となる)。\r
4440                                 {\r
4441                                         var chip = this.listChip[ i ];\r
4442 \r
4443                                         if( chip.bBPMチップである && chip.n整数値・内部番号 == -zz )      // #BPMzz 行より前の行に出現した #BPMzz では、整数値・内部番号は -zz に初期化されている。\r
4444                                                 chip.n整数値・内部番号 = this.n内部番号BPM1to;\r
4445                                 }\r
4446                         }\r
4447                         this.n無限管理BPM[ zz ] = this.n内部番号BPM1to;                 // 次にこの BPM番号 zz を使うBPMチップが現れたら、このBPM値が格納されることになる。\r
4448                         this.n内部番号BPM1to++;             // 内部番号は単純増加連番。\r
4449                         //-----------------\r
4450                         #endregion\r
4451 \r
4452                         return true;\r
4453                 }\r
4454                 private bool t入力・行解析・RESULTIMAGE( string strコマンド, string strパラメータ, string strコメント )\r
4455                 {\r
4456                         // (1) コマンドを処理。\r
4457 \r
4458                         #region [ "RESULTIMAGE" で始まらないコマンドは無効。]\r
4459                         //-----------------\r
4460                         if( !strコマンド.StartsWith( "RESULTIMAGE", StringComparison.OrdinalIgnoreCase ) )\r
4461                                 return false;\r
4462 \r
4463                         strコマンド = strコマンド.Substring( 11 );      // strコマンド から先頭の"RESULTIMAGE"文字を除去。\r
4464                         //-----------------\r
4465                         #endregion\r
4466 \r
4467                         // (2) パラメータを処理。\r
4468                         //     コマンドには "#RESULTIMAGE:" と "#RESULTIMAGE_SS~E" の2種類があり、パラメータの処理はそれぞれ異なる。\r
4469 \r
4470                         if( strコマンド.Length < 2 )\r
4471                         {\r
4472                                 #region [ (A) ランク指定がない場合("#RESULTIMAGE:") → 優先順位が設定されていないすべてのランクで同じパラメータを使用する。]\r
4473                                 //-----------------\r
4474                                 for( int i = 0; i < 7; i++ )\r
4475                                 {\r
4476                                         if( this.nRESULTIMAGE用優先順位[ i ] == 0 )\r
4477                                                 this.RESULTIMAGE[ i ] = strパラメータ.Trim();\r
4478                                 }\r
4479                                 //-----------------\r
4480                                 #endregion\r
4481                         }\r
4482                         else\r
4483                         {\r
4484                                 #region [ (B) ランク指定がある場合("#RESULTIMAGE_SS~E:") → 優先順位に従ってパラメータを記録する。]\r
4485                                 //-----------------\r
4486                                 switch( strコマンド.ToUpper() )\r
4487                                 {\r
4488                                         case "_SS":\r
4489                                                 this.t入力・行解析・RESULTIMAGE・ファイルを設定する( 0, strパラメータ );\r
4490                                                 break;\r
4491 \r
4492                                         case "_S":\r
4493                                                 this.t入力・行解析・RESULTIMAGE・ファイルを設定する( 1, strパラメータ );\r
4494                                                 break;\r
4495 \r
4496                                         case "_A":\r
4497                                                 this.t入力・行解析・RESULTIMAGE・ファイルを設定する( 2, strパラメータ );\r
4498                                                 break;\r
4499 \r
4500                                         case "_B":\r
4501                                                 this.t入力・行解析・RESULTIMAGE・ファイルを設定する( 3, strパラメータ );\r
4502                                                 break;\r
4503 \r
4504                                         case "_C":\r
4505                                                 this.t入力・行解析・RESULTIMAGE・ファイルを設定する( 4, strパラメータ );\r
4506                                                 break;\r
4507 \r
4508                                         case "_D":\r
4509                                                 this.t入力・行解析・RESULTIMAGE・ファイルを設定する( 5, strパラメータ );\r
4510                                                 break;\r
4511 \r
4512                                         case "_E":\r
4513                                                 this.t入力・行解析・RESULTIMAGE・ファイルを設定する( 6, strパラメータ );\r
4514                                                 break;\r
4515                                 }\r
4516                                 //-----------------\r
4517                                 #endregion\r
4518                         }\r
4519 \r
4520                         return true;\r
4521                 }\r
4522                 private void t入力・行解析・RESULTIMAGE・ファイルを設定する( int nランク0to6, string strファイル名 )\r
4523                 {\r
4524                         if( nランク0to6 < 0 || nランク0to6 > 6 )  // 値域チェック。\r
4525                                 return;\r
4526 \r
4527                         // 指定されたランクから上位のすべてのランクについて、ファイル名を更新する。\r
4528 \r
4529                         for( int i = nランク0to6; i >= 0; i-- )\r
4530                         {\r
4531                                 int n優先順位 = 7 - nランク0to6;\r
4532 \r
4533                                 // 現状より優先順位の低い RESULTIMAGE[] に限り、ファイル名を更新できる。\r
4534                                 //(例:#RESULTMOVIE_D が #RESULTIMAGE_A より後に出現しても、#RESULTIMAGE_A で指定されたファイル名を上書きすることはできない。しかしその逆は可能。)\r
4535 \r
4536                                 if( this.nRESULTIMAGE用優先順位[ i ] < n優先順位 )\r
4537                                 {\r
4538                                         this.nRESULTIMAGE用優先順位[ i ] = n優先順位;\r
4539                                         this.RESULTIMAGE[ i ] = strファイル名;\r
4540                                 }\r
4541                         }\r
4542                 }\r
4543                 private bool t入力・行解析・RESULTMOVIE( string strコマンド, string strパラメータ, string strコメント )\r
4544                 {\r
4545                         // (1) コマンドを処理。\r
4546 \r
4547                         #region [ "RESULTMOVIE" で始まらないコマンドは無効。]\r
4548                         //-----------------\r
4549                         if( !strコマンド.StartsWith( "RESULTMOVIE", StringComparison.OrdinalIgnoreCase ) )\r
4550                                 return false;\r
4551 \r
4552                         strコマンド = strコマンド.Substring( 11 );      // strコマンド から先頭の"RESULTMOVIE"文字を除去。\r
4553                         //-----------------\r
4554                         #endregion\r
4555 \r
4556                         // (2) パラメータを処理。\r
4557                         //     コマンドには "#RESULTMOVIE:" と "#RESULTMOVIE_SS~E" の2種類があり、パラメータの処理はそれぞれ異なる。\r
4558 \r
4559                         if( strコマンド.Length < 2 )\r
4560                         {\r
4561                                 #region [ (A) ランク指定がない場合("#RESULTMOVIE:") → 優先順位が設定されていないすべてのランクで同じパラメータを使用する。]\r
4562                                 //-----------------\r
4563                                 for( int i = 0; i < 7; i++ )\r
4564                                 {\r
4565                                         if( this.nRESULTMOVIE用優先順位[ i ] == 0 )\r
4566                                                 this.RESULTMOVIE[ i ] = strパラメータ.Trim();\r
4567                                 }\r
4568                                 //-----------------\r
4569                                 #endregion\r
4570                         }\r
4571                         else\r
4572                         {\r
4573                                 #region [ (B) ランク指定がある場合("#RESULTMOVIE_SS~E:") → 優先順位に従ってパラメータを記録する。]\r
4574                                 //-----------------\r
4575                                 switch( strコマンド.ToUpper() )\r
4576                                 {\r
4577                                         case "_SS":\r
4578                                                 this.t入力・行解析・RESULTMOVIE・ファイルを設定する( 0, strパラメータ );\r
4579                                                 break;\r
4580 \r
4581                                         case "_S":\r
4582                                                 this.t入力・行解析・RESULTMOVIE・ファイルを設定する( 1, strパラメータ );\r
4583                                                 break;\r
4584 \r
4585                                         case "_A":\r
4586                                                 this.t入力・行解析・RESULTMOVIE・ファイルを設定する( 2, strパラメータ );\r
4587                                                 break;\r
4588 \r
4589                                         case "_B":\r
4590                                                 this.t入力・行解析・RESULTMOVIE・ファイルを設定する( 3, strパラメータ );\r
4591                                                 break;\r
4592 \r
4593                                         case "_C":\r
4594                                                 this.t入力・行解析・RESULTMOVIE・ファイルを設定する( 4, strパラメータ );\r
4595                                                 break;\r
4596 \r
4597                                         case "_D":\r
4598                                                 this.t入力・行解析・RESULTMOVIE・ファイルを設定する( 5, strパラメータ );\r
4599                                                 break;\r
4600 \r
4601                                         case "_E":\r
4602                                                 this.t入力・行解析・RESULTMOVIE・ファイルを設定する( 6, strパラメータ );\r
4603                                                 break;\r
4604                                 }\r
4605                                 //-----------------\r
4606                                 #endregion\r
4607                         }\r
4608 \r
4609                         return true;\r
4610                 }\r
4611                 private void t入力・行解析・RESULTMOVIE・ファイルを設定する( int nランク0to6, string strファイル名 )\r
4612                 {\r
4613                         if( nランク0to6 < 0 || nランク0to6 > 6 )  // 値域チェック。\r
4614                                 return;\r
4615 \r
4616                         // 指定されたランクから上位のすべてのランクについて、ファイル名を更新する。\r
4617 \r
4618                         for( int i = nランク0to6; i >= 0; i-- )\r
4619                         {\r
4620                                 int n優先順位 = 7 - nランク0to6;\r
4621 \r
4622                                 // 現状より優先順位の低い RESULTMOVIE[] に限り、ファイル名を更新できる。\r
4623                                 //(例:#RESULTMOVIE_D が #RESULTMOVIE_A より後に出現しても、#RESULTMOVIE_A で指定されたファイル名を上書きすることはできない。しかしその逆は可能。)\r
4624 \r
4625                                 if( this.nRESULTMOVIE用優先順位[ i ] < n優先順位 )\r
4626                                 {\r
4627                                         this.nRESULTMOVIE用優先順位[ i ] = n優先順位;\r
4628                                         this.RESULTMOVIE[ i ] = strファイル名;\r
4629                                 }\r
4630                         }\r
4631                 }\r
4632                 private bool t入力・行解析・RESULTSOUND( string strコマンド, string strパラメータ, string strコメント )\r
4633                 {\r
4634                         // (1) コマンドを処理。\r
4635 \r
4636                         #region [ "RESULTSOUND" で始まらないコマンドは無効。]\r
4637                         //-----------------\r
4638                         if( !strコマンド.StartsWith( "RESULTSOUND", StringComparison.OrdinalIgnoreCase ) )\r
4639                                 return false;\r
4640 \r
4641                         strコマンド = strコマンド.Substring( 11 );      // strコマンド から先頭の"RESULTSOUND"文字を除去。\r
4642                         //-----------------\r
4643                         #endregion\r
4644 \r
4645                         // (2) パラメータを処理。\r
4646                         //     コマンドには "#RESULTSOUND:" と "#RESULTSOUND_SS~E" の2種類があり、パラメータの処理はそれぞれ異なる。\r
4647 \r
4648                         if( strコマンド.Length < 2 )\r
4649                         {\r
4650                                 #region [ (A) ランク指定がない場合("#RESULTSOUND:") → 優先順位が設定されていないすべてのランクで同じパラメータを使用する。]\r
4651                                 //-----------------\r
4652                                 for( int i = 0; i < 7; i++ )\r
4653                                 {\r
4654                                         if( this.nRESULTSOUND用優先順位[ i ] == 0 )\r
4655                                                 this.RESULTSOUND[ i ] = strパラメータ.Trim();\r
4656                                 }\r
4657                                 //-----------------\r
4658                                 #endregion\r
4659                         }\r
4660                         else\r
4661                         {\r
4662                                 #region [ (B) ランク指定がある場合("#RESULTSOUND_SS~E:") → 優先順位に従ってパラメータを記録する。]\r
4663                                 //-----------------\r
4664                                 switch( strコマンド.ToUpper() )\r
4665                                 {\r
4666                                         case "_SS":\r
4667                                                 this.t入力・行解析・RESULTSOUND・ファイルを設定する( 0, strパラメータ );\r
4668                                                 break;\r
4669 \r
4670                                         case "_S":\r
4671                                                 this.t入力・行解析・RESULTSOUND・ファイルを設定する( 1, strパラメータ );\r
4672                                                 break;\r
4673 \r
4674                                         case "_A":\r
4675                                                 this.t入力・行解析・RESULTSOUND・ファイルを設定する( 2, strパラメータ );\r
4676                                                 break;\r
4677 \r
4678                                         case "_B":\r
4679                                                 this.t入力・行解析・RESULTSOUND・ファイルを設定する( 3, strパラメータ );\r
4680                                                 break;\r
4681 \r
4682                                         case "_C":\r
4683                                                 this.t入力・行解析・RESULTSOUND・ファイルを設定する( 4, strパラメータ );\r
4684                                                 break;\r
4685 \r
4686                                         case "_D":\r
4687                                                 this.t入力・行解析・RESULTSOUND・ファイルを設定する( 5, strパラメータ );\r
4688                                                 break;\r
4689 \r
4690                                         case "_E":\r
4691                                                 this.t入力・行解析・RESULTSOUND・ファイルを設定する( 6, strパラメータ );\r
4692                                                 break;\r
4693                                 }\r
4694                                 //-----------------\r
4695                                 #endregion\r
4696                         }\r
4697 \r
4698                         return true;\r
4699                 }\r
4700                 private void t入力・行解析・RESULTSOUND・ファイルを設定する( int nランク0to6, string strファイル名 )\r
4701                 {\r
4702                         if( nランク0to6 < 0 || nランク0to6 > 6 )  // 値域チェック。\r
4703                                 return;\r
4704 \r
4705                         // 指定されたランクから上位のすべてのランクについて、ファイル名を更新する。\r
4706 \r
4707                         for( int i = nランク0to6; i >= 0; i-- )\r
4708                         {\r
4709                                 int n優先順位 = 7 - nランク0to6;\r
4710 \r
4711                                 // 現状より優先順位の低い RESULTSOUND[] に限り、ファイル名を更新できる。\r
4712                                 //(例:#RESULTSOUND_D が #RESULTSOUND_A より後に出現しても、#RESULTSOUND_A で指定されたファイル名を上書きすることはできない。しかしその逆は可能。)\r
4713 \r
4714                                 if( this.nRESULTSOUND用優先順位[ i ] < n優先順位 )\r
4715                                 {\r
4716                                         this.nRESULTSOUND用優先順位[ i ] = n優先順位;\r
4717                                         this.RESULTSOUND[ i ] = strファイル名;\r
4718                                 }\r
4719                         }\r
4720                 }\r
4721                 private bool t入力・行解析・SIZE( string strコマンド, string strパラメータ, string strコメント )\r
4722                 {\r
4723                         // (1) コマンドを処理。\r
4724 \r
4725                         #region [ "SIZE" で始まらないコマンドや、その後ろに2文字(番号)が付随してないコマンドは無効。]\r
4726                         //-----------------\r
4727                         if( !strコマンド.StartsWith( "SIZE", StringComparison.OrdinalIgnoreCase ) )\r
4728                                 return false;\r
4729 \r
4730                         strコマンド = strコマンド.Substring( 4 );       // strコマンド から先頭の"SIZE"文字を除去。\r
4731 \r
4732                         if( strコマンド.Length < 2 )        // サイズ番号の指定がない場合は無効。\r
4733                                 return false;\r
4734                         //-----------------\r
4735                         #endregion\r
4736 \r
4737                         #region [ nWAV番号(36進数2桁)を取得。]\r
4738                         //-----------------\r
4739                         int nWAV番号 = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4740 \r
4741                         if( nWAV番号 < 0 || nWAV番号 >= 36 * 36 )\r
4742                         {\r
4743                                 Trace.TraceError( "SIZEのWAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4744                                 return false;\r
4745                         }\r
4746                         //-----------------\r
4747                         #endregion\r
4748 \r
4749 \r
4750                         // (2) パラメータを処理。\r
4751 \r
4752                         #region [ nサイズ値 を取得する。値は 0~100 に収める。]\r
4753                         //-----------------\r
4754                         int nサイズ値;\r
4755 \r
4756                         if( !int.TryParse( strパラメータ, out nサイズ値 ) )\r
4757                                 return true;    // int変換に失敗しても、この行自体の処理は終えたのでtrueを返す。\r
4758 \r
4759                         nサイズ値 = Math.Min( Math.Max( nサイズ値, 0 ), 100 );  // 0未満は0、100超えは100に強制変換。\r
4760                         //-----------------\r
4761                         #endregion\r
4762 \r
4763                         #region [ nWAV番号で示されるサイズ未設定のWAVチップがあれば、そのサイズを変更する。無限管理に対応。]\r
4764                         //-----------------\r
4765                         if( this.n無限管理SIZE[ nWAV番号 ] == -nWAV番号 )       // 初期状態では n無限管理SIZE[xx] = -xx である。この場合、#SIZExx がまだ出現していないことを意味する。\r
4766                         {\r
4767                                 foreach( CWAV wav in this.listWAV.Values )              // これまでに出てきたWAVチップのうち、該当する(サイズが未設定の)チップのサイズを変更する(仕組み上、必ず後方参照となる)。\r
4768                                 {\r
4769                                         if( wav.nチップサイズ == -nWAV番号 )            // #SIZExx 行より前の行に出現した #WAVxx では、チップサイズは -xx に初期化されている。\r
4770                                                 wav.nチップサイズ = nサイズ値;\r
4771                                 }\r
4772                         }\r
4773                         this.n無限管理SIZE[ nWAV番号 ] = nサイズ値;                   // 次にこの nWAV番号を使うWAVチップが現れたら、負数の代わりに、このサイズ値が格納されることになる。\r
4774                         //-----------------\r
4775                         #endregion\r
4776 \r
4777                         return true;\r
4778                 }\r
4779                 private bool t入力・行解析・WAV( string strコマンド, string strパラメータ, string strコメント )\r
4780                 {\r
4781                         // (1) コマンドを処理。\r
4782 \r
4783                         #region [ "WAV" で始まらないコマンドは無効。]\r
4784                         //-----------------\r
4785                         if( !strコマンド.StartsWith( "WAV", StringComparison.OrdinalIgnoreCase ) )\r
4786                                 return false;\r
4787 \r
4788                         strコマンド = strコマンド.Substring( 3 );       // strコマンド から先頭の"WAV"文字を除去。\r
4789                         //-----------------\r
4790                         #endregion\r
4791 \r
4792                         // (2) パラメータを処理。\r
4793 \r
4794                         if( strコマンド.Length < 2 )\r
4795                                 return false;   // WAV番号 zz がないなら無効。\r
4796 \r
4797                         #region [ WAV番号 zz を取得する。]\r
4798                         //-----------------\r
4799                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4800                         if( zz < 0 || zz >= 36 * 36 )\r
4801                         {\r
4802                                 Trace.TraceError( "WAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4803                                 return false;\r
4804                         }\r
4805                         //-----------------\r
4806                         #endregion\r
4807 \r
4808                         var wav = new CWAV() {\r
4809                                 n内部番号 = this.n内部番号WAV1to,\r
4810                                 n表記上の番号 = zz,\r
4811                                 nチップサイズ = this.n無限管理SIZE[ zz ],\r
4812                                 n位置 = this.n無限管理PAN[ zz ],\r
4813                                 n音量 = this.n無限管理VOL[ zz ],\r
4814                                 strファイル名 = strパラメータ,\r
4815                                 strコメント文 = strコメント,\r
4816                         };\r
4817 \r
4818                         #region [ WAVリストに {内部番号, wav} の組を登録。]\r
4819                         //-----------------\r
4820                         this.listWAV.Add( this.n内部番号WAV1to, wav );\r
4821                         //-----------------\r
4822                         #endregion\r
4823 \r
4824                         #region [ WAV番号が zz である内部番号未設定のWAVチップがあれば、その内部番号を変更する。無限管理対応。]\r
4825                         //-----------------\r
4826                         if( this.n無限管理WAV[ zz ] == -zz )        // 初期状態では n無限管理WAV[zz] = -zz である。この場合、#WAVzz がまだ出現していないことを意味する。\r
4827                         {\r
4828                                 for( int i = 0; i < this.listChip.Count; i++ )  // これまでに出てきたチップのうち、該当する(内部番号が未設定の)WAVチップの値を変更する(仕組み上、必ず後方参照となる)。\r
4829                                 {\r
4830                                         var chip = this.listChip[ i ];\r
4831 \r
4832                                         if( chip.bWAVを使うチャンネルである && ( chip.n整数値・内部番号 == -zz ) )   // この #WAVzz 行より前の行に出現した #WAVzz では、整数値・内部番号は -zz に初期化されている。\r
4833                                                 chip.n整数値・内部番号 = this.n内部番号WAV1to;\r
4834                                 }\r
4835                         }\r
4836                         this.n無限管理WAV[ zz ] = this.n内部番号WAV1to;                 // 次にこの WAV番号 zz を使うWAVチップが現れたら、この内部番号が格納されることになる。\r
4837                         this.n内部番号WAV1to++;             // 内部番号は単純増加連番。\r
4838                         //-----------------\r
4839                         #endregion\r
4840 \r
4841                         return true;\r
4842                 }\r
4843                 private bool t入力・行解析・WAVPAN_PAN( string strコマンド, string strパラメータ, string strコメント )\r
4844                 {\r
4845                         // (1) コマンドを処理。\r
4846 \r
4847                         #region [ "WAVPAN" or "PAN" で始まらないコマンドは無効。]\r
4848                         //-----------------\r
4849                         if( strコマンド.StartsWith( "WAVPAN", StringComparison.OrdinalIgnoreCase ) )\r
4850                                 strコマンド = strコマンド.Substring( 6 );               // strコマンド から先頭の"WAVPAN"文字を除去。\r
4851 \r
4852                         else if( strコマンド.StartsWith( "PAN", StringComparison.OrdinalIgnoreCase ) )\r
4853                                 strコマンド = strコマンド.Substring( 3 );               // strコマンド から先頭の"PAN"文字を除去。\r
4854 \r
4855                         else\r
4856                                 return false;\r
4857                         //-----------------\r
4858                         #endregion\r
4859 \r
4860                         // (2) パラメータを処理。\r
4861 \r
4862                         if( strコマンド.Length < 2 )\r
4863                                 return false;   // WAV番号 zz がないなら無効。\r
4864 \r
4865                         #region [ WAV番号 zz を取得する。]\r
4866                         //-----------------\r
4867                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4868                         if( zz < 0 || zz >= 36 * 36 )\r
4869                         {\r
4870                                 Trace.TraceError( "WAVPAN(PAN)のWAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4871                                 return false;\r
4872                         }\r
4873                         //-----------------\r
4874                         #endregion\r
4875 \r
4876                         #region [ WAV番号 zz を持つWAVチップの位置を変更する。無限定義対応。]\r
4877                         //-----------------\r
4878                         int n位置;\r
4879                         if( int.TryParse( strパラメータ, out n位置 ) )\r
4880                         {\r
4881                                 n位置 = Math.Min( Math.Max( n位置, -100 ), 100 );   // -100~+100 に丸める\r
4882 \r
4883                                 if( this.n無限管理PAN[ zz ] == ( -10000 - zz ) )    // 初期状態では n無限管理PAN[zz] = -10000 - zz である。この場合、#WAVPANzz, #PANzz がまだ出現していないことを意味する。\r
4884                                 {\r
4885                                         foreach( CWAV wav in this.listWAV.Values )      // これまでに出てきたチップのうち、該当する(位置が未設定の)WAVチップの値を変更する(仕組み上、必ず後方参照となる)。\r
4886                                         {\r
4887                                                 if( wav.n位置 == ( -10000 - zz ) )    // #WAVPANzz, #PANzz 行より前の行に出現した #WAVzz では、位置は -10000-zz に初期化されている。\r
4888                                                         wav.n位置 = n位置;\r
4889                                         }\r
4890                                 }\r
4891                                 this.n無限管理PAN[ zz ] = n位置;                  // 次にこの WAV番号 zz を使うWAVチップが現れたら、この位置が格納されることになる。\r
4892                         }\r
4893                         //-----------------\r
4894                         #endregion\r
4895 \r
4896                         return true;\r
4897                 }\r
4898                 private bool t入力・行解析・WAVVOL_VOLUME( string strコマンド, string strパラメータ, string strコメント )\r
4899                 {\r
4900                         // (1) コマンドを処理。\r
4901 \r
4902                         #region [ "WAVCOL" or "VOLUME" で始まらないコマンドは無効。]\r
4903                         //-----------------\r
4904                         if( strコマンド.StartsWith( "WAVVOL", StringComparison.OrdinalIgnoreCase ) )\r
4905                                 strコマンド = strコマンド.Substring( 6 );               // strコマンド から先頭の"WAVVOL"文字を除去。\r
4906 \r
4907                         else if( strコマンド.StartsWith( "VOLUME", StringComparison.OrdinalIgnoreCase ) )\r
4908                                 strコマンド = strコマンド.Substring( 6 );               // strコマンド から先頭の"VOLUME"文字を除去。\r
4909 \r
4910                         else\r
4911                                 return false;\r
4912                         //-----------------\r
4913                         #endregion\r
4914 \r
4915                         // (2) パラメータを処理。\r
4916 \r
4917                         if( strコマンド.Length < 2 )\r
4918                                 return false;   // WAV番号 zz がないなら無効。\r
4919 \r
4920                         #region [ WAV番号 zz を取得する。]\r
4921                         //-----------------\r
4922                         int zz = C変換.n36進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 0, 2 ) );\r
4923                         if( zz < 0 || zz >= 36 * 36 )\r
4924                         {\r
4925                                 Trace.TraceError( "WAV番号に 00~ZZ 以外の値または不正な文字列が指定されました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
4926                                 return false;\r
4927                         }\r
4928                         //-----------------\r
4929                         #endregion\r
4930 \r
4931                         #region [ WAV番号 zz を持つWAVチップの音量を変更する。無限定義対応。]\r
4932                         //-----------------\r
4933                         int n音量;\r
4934                         if( int.TryParse( strパラメータ, out n音量 ) )\r
4935                         {\r
4936                                 n音量 = Math.Min( Math.Max( n音量, 0 ), 100 );      // 0~100に丸める。\r
4937 \r
4938                                 if( this.n無限管理VOL[ zz ] == -zz )        // 初期状態では n無限管理VOL[zz] = - zz である。この場合、#WAVVOLzz, #VOLUMEzz がまだ出現していないことを意味する。\r
4939                                 {\r
4940                                         foreach( CWAV wav in this.listWAV.Values )      // これまでに出てきたチップのうち、該当する(音量が未設定の)WAVチップの値を変更する(仕組み上、必ず後方参照となる)。\r
4941                                         {\r
4942                                                 if( wav.n音量 == -zz )        // #WAVVOLzz, #VOLUMEzz 行より前の行に出現した #WAVzz では、音量は -zz に初期化されている。\r
4943                                                         wav.n音量 = n音量;\r
4944                                         }\r
4945                                 }\r
4946                                 this.n無限管理VOL[ zz ] = n音量;                  // 次にこの WAV番号 zz を使うWAVチップが現れたら、この音量が格納されることになる。\r
4947                         }\r
4948                         //-----------------\r
4949                         #endregion\r
4950 \r
4951                         return true;\r
4952                 }\r
4953                 private bool t入力・行解析・チップ配置( string strコマンド, string strパラメータ, string strコメント )\r
4954                 {\r
4955                         // (1) コマンドを処理。\r
4956 \r
4957                         if( strコマンド.Length != 5 )       // コマンドは必ず5文字であること。\r
4958                                 return false;\r
4959 \r
4960                         #region [ n小節番号 を取得する。]\r
4961                         //-----------------\r
4962                         int n小節番号 = C変換.n小節番号の文字列3桁を数値に変換して返す( strコマンド.Substring( 0, 3 ) );\r
4963                         if( n小節番号 < 0 )\r
4964                                 return false;\r
4965 \r
4966                         n小節番号++;        // 先頭に空の1小節を設ける。\r
4967                         //-----------------\r
4968                         #endregion\r
4969 \r
4970                         #region [ nチャンネル番号 を取得する。]\r
4971                         //-----------------\r
4972                         int nチャンネル番号 = -1;\r
4973 \r
4974                         // ファイルフォーマットによって処理が異なる。\r
4975 \r
4976                         if( this.e種別 == E種別.GDA || this.e種別 == E種別.G2D )\r
4977                         {\r
4978                                 #region [ (A) GDA, G2D の場合:チャンネル文字列をDTXのチャンネル番号へ置き換える。]\r
4979                                 //-----------------\r
4980                                 string strチャンネル文字列 = strコマンド.Substring( 3, 2 );\r
4981 \r
4982                                 foreach( STGDAPARAM param in this.stGDAParam )\r
4983                                 {\r
4984                                         if( strチャンネル文字列.Equals( param.strGDAのチャンネル文字列, StringComparison.OrdinalIgnoreCase ) )\r
4985                                         {\r
4986                                                 nチャンネル番号 = param.nDTXのチャンネル番号;\r
4987                                                 break;  // 置き換え成功\r
4988                                         }\r
4989                                 }\r
4990                                 if( nチャンネル番号 < 0 )\r
4991                                         return false;   // 置き換え失敗\r
4992                                 //-----------------\r
4993                                 #endregion\r
4994                         }\r
4995                         else\r
4996                         {\r
4997                                 #region [ (B) その他の場合:チャンネル番号は16進数2桁。]\r
4998                                 //-----------------\r
4999                                 nチャンネル番号 = C変換.n16進数2桁の文字列を数値に変換して返す( strコマンド.Substring( 3, 2 ) );\r
5000 \r
5001                                 if( nチャンネル番号 < 0 )\r
5002                                         return false;\r
5003                                 //-----------------\r
5004                                 #endregion\r
5005                         }\r
5006                         //-----------------\r
5007                         #endregion\r
5008                         #region [ 取得したチャンネル番号で、this.bチップがある に該当があれば設定する。]\r
5009                         //-----------------\r
5010                         if( ( nチャンネル番号 >= 0x11 ) && ( nチャンネル番号 <= 0x1a ) )\r
5011                         {\r
5012                                 this.bチップがある.Drums = true;\r
5013                         }\r
5014                         else if( ( nチャンネル番号 >= 0x20 ) && ( nチャンネル番号 <= 0x27 ) )\r
5015                         {\r
5016                                 this.bチップがある.Guitar = true;\r
5017                         }\r
5018                         else if( ( nチャンネル番号 >= 0xA0 ) && ( nチャンネル番号 <= 0xa7 ) )\r
5019                         {\r
5020                                 this.bチップがある.Bass = true;\r
5021                         }\r
5022                         switch( nチャンネル番号 )\r
5023                         {\r
5024                                 case 0x18:\r
5025                                         this.bチップがある.HHOpen = true;\r
5026                                         break;\r
5027 \r
5028                                 case 0x19:\r
5029                                         this.bチップがある.Ride = true;\r
5030                                         break;\r
5031 \r
5032                                 case 0x1a:\r
5033                                         this.bチップがある.LeftCymbal = true;\r
5034                                         break;\r
5035 \r
5036                                 case 0x20:\r
5037                                         this.bチップがある.OpenGuitar = true;\r
5038                                         break;\r
5039 \r
5040                                 case 0xA0:\r
5041                                         this.bチップがある.OpenBass = true;\r
5042                                         break;\r
5043                         }\r
5044                         //-----------------\r
5045                         #endregion\r
5046 \r
5047 \r
5048                         // (2) Ch.02を処理。\r
5049 \r
5050                         #region [ 小節長変更(Ch.02)は他のチャンネルとはパラメータが特殊なので、先にとっとと終わらせる。 ]\r
5051                         //-----------------\r
5052                         if( nチャンネル番号 == 0x02 )\r
5053                         {\r
5054                                 // 小節長倍率を取得する。\r
5055 \r
5056                                 double db小節長倍率 = 1.0;\r
5057                                 //if( !double.TryParse( strパラメータ, out result ) )\r
5058                                 if( !this.TryParse( strパラメータ, out db小節長倍率 ) )                       // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point\r
5059                                 {\r
5060                                         Trace.TraceError( "小節長倍率に不正な値を指定しました。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
5061                                         return false;\r
5062                                 }\r
5063 \r
5064                                 // 小節長倍率チップを配置する。\r
5065 \r
5066                                 this.listChip.Insert(\r
5067                                         0,\r
5068                                         new CChip() {\r
5069                                                 nチャンネル番号 = nチャンネル番号,\r
5070                                                 db実数値 = db小節長倍率,\r
5071                                                 n発声位置 = n小節番号 * 384,\r
5072                                         } );\r
5073 \r
5074                                 return true;    // 配置終了。\r
5075                         }\r
5076                         //-----------------\r
5077                         #endregion\r
5078 \r
5079 \r
5080                         // (3) パラメータを処理。\r
5081 \r
5082                         if( string.IsNullOrEmpty( strパラメータ ) )                // パラメータはnullまたは空文字列ではないこと。\r
5083                                 return false;\r
5084 \r
5085                         #region [ strパラメータ にオブジェクト記述を格納し、その n文字数 をカウントする。]\r
5086                         //-----------------\r
5087                         int n文字数 = 0;\r
5088 \r
5089                         var sb = new StringBuilder( strパラメータ.Length );\r
5090 \r
5091                         // strパラメータを先頭から1文字ずつ見ながら正規化(無効文字('_')を飛ばしたり不正な文字でエラーを出したり)し、sb へ格納する。\r
5092 \r
5093                         CharEnumerator ce = strパラメータ.GetEnumerator();\r
5094                         while( ce.MoveNext() )\r
5095                         {\r
5096                                 if( ce.Current == '_' )         // '_' は無視。\r
5097                                         continue;\r
5098 \r
5099                                 if( C変換.str36進数文字.IndexOf( ce.Current ) < 0 )       // オブジェクト記述は36進数文字であること。\r
5100                                 {\r
5101                                         Trace.TraceError( "不正なオブジェクト指定があります。[{0}: {1}行]", this.strファイル名の絶対パス, this.n現在の行数 );\r
5102                                         return false;\r
5103                                 }\r
5104 \r
5105                                 sb.Append( ce.Current );\r
5106                                 n文字数++;\r
5107                         }\r
5108 \r
5109                         strパラメータ = sb.ToString();     // 正規化された文字列になりました。\r
5110 \r
5111                         if( ( n文字数 % 2 ) != 0 )           // パラメータの文字数が奇数の場合、最後の1文字を無視する。\r
5112                                 n文字数--;\r
5113                         //-----------------\r
5114                         #endregion\r
5115 \r
5116 \r
5117                         // (4) パラメータをオブジェクト数値に分解して配置する。\r
5118 \r
5119                         for( int i = 0; i < ( n文字数 / 2 ); i++ )   // 2文字で1オブジェクト数値\r
5120                         {\r
5121                                 #region [ nオブジェクト数値 を1つ取得する。'00' なら無視。]\r
5122                                 //-----------------\r
5123                                 int nオブジェクト数値 = 0;\r
5124 \r
5125                                 if( nチャンネル番号 == 0x03 )\r
5126                                 {\r
5127                                         // Ch.03 のみ 16進数2桁。\r
5128                                         nオブジェクト数値 = C変換.n16進数2桁の文字列を数値に変換して返す( strパラメータ.Substring( i * 2, 2 ) );\r
5129                                 }\r
5130                                 else\r
5131                                 {\r
5132                                         // その他のチャンネルは36進数2桁。\r
5133                                         nオブジェクト数値 = C変換.n36進数2桁の文字列を数値に変換して返す( strパラメータ.Substring( i * 2, 2 ) );\r
5134                                 }\r
5135 \r
5136                                 if( nオブジェクト数値 == 0x00 )\r
5137                                         continue;\r
5138                                 //-----------------\r
5139                                 #endregion\r
5140 \r
5141                                 // オブジェクト数値に対応するチップを生成。\r
5142 \r
5143                                 var chip = new CChip();\r
5144 \r
5145                                 chip.nチャンネル番号 = nチャンネル番号;\r
5146                                 chip.n発声位置 = ( n小節番号 * 384 ) + ( ( 384 * i ) / ( n文字数 / 2 ) );\r
5147                                 chip.n整数値 = nオブジェクト数値;\r
5148                                 chip.n整数値・内部番号 = nオブジェクト数値;\r
5149 \r
5150                                 #region [ chip.e楽器パート = ... ]\r
5151                                 //-----------------\r
5152                                 if( ( nチャンネル番号 >= 0x11 ) && ( nチャンネル番号 <= 0x1A ) )\r
5153                                 {\r
5154                                         chip.e楽器パート = E楽器パート.DRUMS;\r
5155                                 }\r
5156                                 if( ( nチャンネル番号 >= 0x20 ) && ( nチャンネル番号 <= 0x27 ) )\r
5157                                 {\r
5158                                         chip.e楽器パート = E楽器パート.GUITAR;\r
5159                                 }\r
5160                                 if( ( nチャンネル番号 >= 160 ) && ( nチャンネル番号 <= 0xA7 ) )\r
5161                                 {\r
5162                                         chip.e楽器パート = E楽器パート.BASS;\r
5163                                 }\r
5164                                 //-----------------\r
5165                                 #endregion\r
5166 \r
5167                                 #region [ 無限定義への対応 → 内部番号の取得。]\r
5168                                 //-----------------\r
5169                                 if( chip.bWAVを使うチャンネルである )\r
5170                                 {\r
5171                                         chip.n整数値・内部番号 = this.n無限管理WAV[ nオブジェクト数値 ];    // これが本当に一意なWAV番号となる。(無限定義の場合、chip.n整数値 は一意である保証がない。)\r
5172                                 }\r
5173                                 else if( chip.bBPMチップである )\r
5174                                 {\r
5175                                         chip.n整数値・内部番号 = this.n無限管理BPM[ nオブジェクト数値 ];    // これが本当に一意なBPM番号となる。(同上。)\r
5176                                 }\r
5177                                 //-----------------\r
5178                                 #endregion\r
5179 \r
5180                                 #region [ フィルインON/OFFチャンネル(Ch.53)の場合、発声位置を少し前後にずらす。]\r
5181                                 //-----------------\r
5182                                 if( nチャンネル番号 == 0x53 )\r
5183                                 {\r
5184                                         // ずらすのは、フィルインONチップと同じ位置にいるチップでも確実にフィルインが発動し、\r
5185                                         // 同様に、フィルインOFFチップと同じ位置にいるチップでも確実にフィルインが終了するようにするため。\r
5186 \r
5187                                         if( ( nオブジェクト数値 > 0 ) && ( nオブジェクト数値 != 2 ) )\r
5188                                         {\r
5189                                                 chip.n発声位置 -= 32;       // 384÷32=12 ということで、フィルインONチップは12分音符ほど前へ移動。\r
5190                                         }\r
5191                                         else if( nオブジェクト数値 == 2 )\r
5192                                         {\r
5193                                                 chip.n発声位置 += 32;       // 同じく、フィルインOFFチップは12分音符ほど後ろへ移動。\r
5194                                         }\r
5195                                 }\r
5196                                 //-----------------\r
5197                                 #endregion\r
5198 \r
5199                                 // チップを配置。\r
5200 \r
5201                                 this.listChip.Add( chip );\r
5202                         }\r
5203                         return true;\r
5204                 }\r
5205                 #region [#23880 2010.12.30 yyagi: コンマとスペースの両方を小数点として扱うTryParse]\r
5206                 /// <summary>\r
5207                 /// 小数点としてコンマとピリオドの両方を受け付けるTryParse()\r
5208                 /// </summary>\r
5209                 /// <param name="s">strings convert to double</param>\r
5210                 /// <param name="result">parsed double value</param>\r
5211                 /// <returns>s が正常に変換された場合は true。それ以外の場合は false。</returns>\r
5212                 /// <exception cref="ArgumentException">style が NumberStyles 値でないか、style に NumberStyles.AllowHexSpecifier 値が含まれている</exception>\r
5213                 private bool TryParse(string s, out double result) {    // #23880 2010.12.30 yyagi: alternative TryParse to permit both '.' and ',' for decimal point\r
5214                                                                                                                                 // EU諸国での #BPM 123,45 のような記述に対応するため、\r
5215                                                                                                                                 // 小数点の最終位置を検出して、それをlocaleにあった\r
5216                                                                                                                                 // 文字に置き換えてからTryParse()する\r
5217                                                                                                                                 // 桁区切りの文字はスキップする\r
5218 \r
5219                         const string DecimalSeparators = ".,";                          // 小数点文字\r
5220                         const string GroupSeparators = ".,' ";                          // 桁区切り文字\r
5221                         const string NumberSymbols = "0123456789";                      // 数値文字\r
5222 \r
5223                         int len = s.Length;                                                                     // 文字列長\r
5224                         int decimalPosition = len;                                                      // 真の小数点の位置 最初は文字列終端位置に仮置きする\r
5225 \r
5226                         for (int i = 0; i < len; i++) {                                                 // まず、真の小数点(一番最後に現れる小数点)の位置を求める\r
5227                                 char c = s[i];\r
5228                                 if (NumberSymbols.IndexOf(c) >= 0) {                            // 数値だったらスキップ\r
5229                                         continue;\r
5230                                 } else if (DecimalSeparators.IndexOf(c) >= 0) {         // 小数点文字だったら、その都度位置を上書き記憶\r
5231                                         decimalPosition = i;\r
5232                                 } else if (GroupSeparators.IndexOf(c) >= 0) {           // 桁区切り文字の場合もスキップ\r
5233                                         continue;\r
5234                                 } else {                                                                                        // 数値・小数点・区切り文字以外がきたらループ終了\r
5235                                         break;\r
5236                                 }\r
5237                         }\r
5238 \r
5239                         StringBuilder decimalStr = new StringBuilder(16);\r
5240                         for (int i = 0; i < len; i++) {                                                 // 次に、localeにあった数値文字列を生成する\r
5241                                 char c = s[i];\r
5242                                 if (NumberSymbols.IndexOf(c) >= 0) {                            // 数値だったら\r
5243                                         decimalStr.Append(c);                                                   // そのままコピー\r
5244                                 } else if (DecimalSeparators.IndexOf(c) >= 0) {         // 小数点文字だったら\r
5245                                         if (i == decimalPosition) {                                             // 最後に出現した小数点文字なら、localeに合った小数点を出力する\r
5246                                                 decimalStr.Append(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);\r
5247                                         }\r
5248                                 } else if (GroupSeparators.IndexOf(c) >= 0) {           // 桁区切り文字だったら\r
5249                                         continue;                                                                               // 何もしない(スキップ)\r
5250                                 } else {\r
5251                                         break;\r
5252                                 }\r
5253                         }\r
5254                         return double.TryParse(decimalStr.ToString(), out result);      // 最後に、自分のlocale向けの文字列に対してTryParse実行\r
5255                 }\r
5256                 #endregion\r
5257                 //-----------------\r
5258                 #endregion\r
5259         }\r
5260 }\r