OSDN Git Service

#xxxxx Matixx風選曲画面にBPM表示を追加
[dtxmaniaxg-verk/dtxmaniaxg-verk-git.git] / DTXManiaプロジェクト / コード / ステージ / 05.選曲 / CStage選曲.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Runtime.InteropServices;
5 using System.Drawing;
6 using System.Diagnostics;
7 using System.IO;
8 using FDK;
9
10 namespace DTXMania
11 {
12         internal class CStage選曲 : CStage
13         {
14                 // プロパティ
15                 public int nスクロールバー相対y座標
16                 {
17                         get
18                         {
19                                 if ( act曲リスト != null )
20                                 {
21                                         return act曲リスト.nスクロールバー相対y座標;
22                                 }
23                                 else
24                                 {
25                                         return 0;
26                                 }
27                         }
28                 }
29                 public bool bIsEnumeratingSongs
30                 {
31                         get
32                         {
33                                 return act曲リスト.bIsEnumeratingSongs;
34                         }
35                         set
36                         {
37                                 act曲リスト.bIsEnumeratingSongs = value;
38                         }
39                 }
40                 public bool bスクロール中
41                 {
42                         get
43                         {
44                                 return this.act曲リスト.bスクロール中;
45                         }
46                 }
47                 public int n確定された曲の難易度
48                 {
49                         get;
50                         private set;
51                 }
52                 public Cスコア r確定されたスコア
53                 {
54                         get;
55                         private set;
56                 }
57                 public C曲リストノード r確定された曲 
58                 {
59                         get;
60                         private set;
61                 }
62                 public int n現在選択中の曲の難易度
63                 {
64                         get
65                         {
66                                 return this.act曲リスト.n現在選択中の曲の現在の難易度レベル;
67                         }
68                 }
69                 public Cスコア r現在選択中のスコア
70                 {
71                         get
72                         {
73                                 return this.act曲リスト.r現在選択中のスコア;
74                         }
75                 }
76                 public C曲リストノード r現在選択中の曲
77                 {
78                         get
79                         {
80                                 return this.act曲リスト.r現在選択中の曲;
81                         }
82                 }
83
84                 // コンストラクタ
85                 public CStage選曲()
86                 {
87                         base.eステージID = CStage.Eステージ.選曲;
88                         base.eフェーズID = CStage.Eフェーズ.共通_通常状態;
89                         base.b活性化してない = true;
90                         base.list子Activities.Add( this.actオプションパネル = new CActオプションパネル() );
91                         base.list子Activities.Add( this.actFIFO = new CActFIFOBlack() );
92                         base.list子Activities.Add( this.actFIfrom結果画面 = new CActFIFOBlack() );
93                         base.list子Activities.Add( this.actFOtoNowLoading = new CActFIFOBlack() );     // #27787 2012.3.10 yyagi 曲決定時の画面フェードアウトの省略
94                         base.list子Activities.Add( this.act曲リスト = new CActSelect曲リスト共通() );
95                         base.list子Activities.Add( this.actステータスパネル = new CActSelectステータスパネル共通() );
96                         base.list子Activities.Add( this.act演奏履歴パネル = new CActSelect演奏履歴パネル() );
97                         base.list子Activities.Add( this.actPresound = new CActSelectPresound() );
98                         base.list子Activities.Add( this.actArtistComment = new CActSelectArtistComment() );
99                         base.list子Activities.Add( this.actInformation = new CActSelectInformation() );
100                         base.list子Activities.Add( this.actSortSongs = new CActSortSongs() );
101                         base.list子Activities.Add( this.actShowCurrentPosition = new CActSelectShowCurrentPosition共通() );
102                         base.list子Activities.Add( this.actQuickConfig = new CActSelectQuickConfig() );
103
104                         this.CommandHistory = new CCommandHistory();            // #24063 2011.1.16 yyagi
105                 }
106                 
107                 
108                 // メソッド
109
110                 public void t選択曲変更通知()
111                 {
112                         this.actPresound.t選択曲が変更された();
113                         this.act演奏履歴パネル.t選択曲が変更された();
114                         this.actステータスパネル.t選択曲が変更された();
115                         this.actArtistComment.t選択曲が変更された();
116
117                         #region [ プラグインにも通知する(BOX, RANDOM, BACK なら通知しない)]
118                         //---------------------
119                         if( CDTXMania.app != null )
120                         {
121                                 var c曲リストノード = CDTXMania.stage選曲.r現在選択中の曲;
122                                 var cスコア = CDTXMania.stage選曲.r現在選択中のスコア;
123                 if( CDTXMania.bXGRelease ) {
124                     c曲リストノード = CDTXMania.stage選曲XG.r現在選択中の曲;
125                     cスコア = CDTXMania.stage選曲GITADORA.r現在選択中のスコア;
126                 } else {
127                     c曲リストノード = CDTXMania.stage選曲GITADORA.r現在選択中の曲;
128                     cスコア = CDTXMania.stage選曲GITADORA.r現在選択中のスコア;
129                 }
130
131                                 if( c曲リストノード != null && cスコア != null && c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )
132                                 {
133                                         string str選択曲ファイル名 = cスコア.ファイル情報.ファイルの絶対パス;
134                                         CSetDef setDef = null;
135                                         int nブロック番号inSetDef = -1;
136                                         int n曲番号inブロック = -1;
137
138                                         if( !string.IsNullOrEmpty( c曲リストノード.pathSetDefの絶対パス ) && File.Exists( c曲リストノード.pathSetDefの絶対パス ) )
139                                         {
140                                                 setDef = new CSetDef( c曲リストノード.pathSetDefの絶対パス );
141                                                 nブロック番号inSetDef = c曲リストノード.SetDefのブロック番号;
142                         if( CDTXMania.bXGRelease ) n曲番号inブロック = CDTXMania.stage選曲XG.act曲リスト.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( c曲リストノード );
143                         else n曲番号inブロック = CDTXMania.stage選曲GITADORA.act曲リスト.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( c曲リストノード );
144                                         }
145
146                                         foreach( CDTXMania.STPlugin stPlugin in CDTXMania.app.listプラグイン )
147                                         {
148                                                 Directory.SetCurrentDirectory( stPlugin.strプラグインフォルダ );
149                                                 stPlugin.plugin.On選択曲変更( str選択曲ファイル名, setDef, nブロック番号inSetDef, n曲番号inブロック );
150                                                 Directory.SetCurrentDirectory( CDTXMania.strEXEのあるフォルダ );
151                                         }
152                                 }
153                         }
154                         //---------------------
155                         #endregion
156                 }
157
158                 // CStage 実装
159
160                 /// <summary>
161                 /// 曲リストをリセットする
162                 /// </summary>
163                 /// <param name="cs"></param>
164                 public void Refresh( CSongs管理 cs, bool bRemakeSongTitleBar)
165                 {
166                         this.act曲リスト.Refresh( cs, bRemakeSongTitleBar );
167                 }
168
169                 public override void On活性化()
170                 {
171                         Trace.TraceInformation( "選曲ステージを活性化します。" );
172                         Trace.Indent();
173                         try
174                         {
175                                 this.eフェードアウト完了時の戻り値 = E戻り値.継続;
176                                 this.bBGM再生済み = false;
177                                 for( int i = 0; i < 4; i++ )
178                                         this.ctキー反復用[ i ] = new CCounter( 0, 0, 0, CDTXMania.Timer );
179                 this.ct決定演出待機 = new CCounter();
180                 this.b決定演出カウンタ使用中 = false;
181                                 base.On活性化();
182
183                                 this.actステータスパネル.t選択曲が変更された();        // 最大ランクを更新
184                         }
185                         finally
186                         {
187                                 Trace.TraceInformation( "選曲ステージの活性化を完了しました。" );
188                                 Trace.Unindent();
189                         }
190                 }
191                 public override void On非活性化()
192                 {
193                         Trace.TraceInformation( "選曲ステージを非活性化します。" );
194                         Trace.Indent();
195                         try
196                         {
197                                 for( int i = 0; i < 4; i++ )
198                                 {
199                                         this.ctキー反復用[ i ] = null;
200                                 }
201                 this.ct決定演出待機 = null;
202                                 base.On非活性化();
203                         }
204                         finally
205                         {
206                                 Trace.TraceInformation( "選曲ステージの非活性化を完了しました。" );
207                                 Trace.Unindent();
208                         }
209                 }
210                 public override void OnManagedリソースの作成()
211                 {
212
213                 }
214                 public override void OnManagedリソースの解放()
215                 {
216
217                 }
218
219                 public enum E戻り値 : int
220                 {
221                         継続,
222                         タイトルに戻る,
223                         選曲した,
224                         オプション呼び出し,
225                         コンフィグ呼び出し,
226                         スキン変更
227                 }
228                 
229
230                 // その他
231
232                 #region [ private ]
233                 //-----------------
234                 [StructLayout( LayoutKind.Sequential )]
235                 protected struct STキー反復用カウンタ
236                 {
237                         public CCounter Up;
238                         public CCounter Down;
239                         public CCounter R;
240                         public CCounter B;
241                         public CCounter this[ int index ]
242                         {
243                                 get
244                                 {
245                                         switch( index )
246                                         {
247                                                 case 0:
248                                                         return this.Up;
249
250                                                 case 1:
251                                                         return this.Down;
252
253                                                 case 2:
254                                                         return this.R;
255
256                                                 case 3:
257                                                         return this.B;
258                                         }
259                                         throw new IndexOutOfRangeException();
260                                 }
261                                 set
262                                 {
263                                         switch( index )
264                                         {
265                                                 case 0:
266                                                         this.Up = value;
267                                                         return;
268
269                                                 case 1:
270                                                         this.Down = value;
271                                                         return;
272
273                                                 case 2:
274                                                         this.R = value;
275                                                         return;
276
277                                                 case 3:
278                                                         this.B = value;
279                                                         return;
280                                         }
281                                         throw new IndexOutOfRangeException();
282                                 }
283                         }
284                 }
285                 protected CActSelectArtistComment actArtistComment;
286                 protected CActFIFOBlack actFIFO;
287                 protected CActFIFOBlack actFIfrom結果画面;
288                 protected CActFIFOBlack actFOtoNowLoading;      // #27787 2012.3.10 yyagi 曲決定時の画面フェードアウトの省略
289                 protected CActSelectInformation actInformation;
290                 protected CActSelectPresound actPresound;
291                 protected CActオプションパネル actオプションパネル;
292                 public  CActSelectステータスパネル共通 actステータスパネル;
293                 protected CActSelect演奏履歴パネル act演奏履歴パネル;
294                 public  CActSelect曲リスト共通 act曲リスト;
295                 protected CActSelectShowCurrentPosition共通 actShowCurrentPosition;
296
297                 protected CActSortSongs actSortSongs;
298                 protected CActSelectQuickConfig actQuickConfig;
299
300                 protected bool bBGM再生済み;
301                 protected STキー反復用カウンタ ctキー反復用;
302                 public CCounter ct登場時アニメ用共通;
303         public CCounter ct決定演出待機; //テスト
304         protected bool b決定演出カウンタ使用中;
305                 protected E戻り値 eフェードアウト完了時の戻り値;
306
307
308                 protected struct STCommandTime          // #24063 2011.1.16 yyagi コマンド入力時刻の記録用
309                 {
310                         public E楽器パート eInst;          // 使用楽器
311                         public EパッドFlag ePad;             // 押されたコマンド(同時押しはOR演算で列挙する)
312                         public long time;                               // コマンド入力時刻
313                 }
314                 protected class CCommandHistory         // #24063 2011.1.16 yyagi コマンド入力履歴を保持・確認するクラス
315                 {
316                         readonly int buffersize = 16;
317                         private List<STCommandTime> stct;
318
319                         public CCommandHistory()                // コンストラクタ
320                         {
321                                 stct = new List<STCommandTime>( buffersize );
322                         }
323
324                         /// <summary>
325                         /// コマンド入力履歴へのコマンド追加
326                         /// </summary>
327                         /// <param name="_eInst">楽器の種類</param>
328                         /// <param name="_ePad">入力コマンド(同時押しはOR演算で列挙すること)</param>
329                         public void Add( E楽器パート _eInst, EパッドFlag _ePad )
330                         {
331                                 STCommandTime _stct = new STCommandTime {
332                                         eInst = _eInst,
333                                         ePad = _ePad,
334                                         time = CDTXMania.Timer.n現在時刻
335                                 };
336
337                                 if ( stct.Count >= buffersize )
338                                 {
339                                         stct.RemoveAt( 0 );
340                                 }
341                                 stct.Add(_stct);
342 //Debug.WriteLine( "CMDHIS: 楽器=" + _stct.eInst + ", CMD=" + _stct.ePad + ", time=" + _stct.time );
343                         }
344                         public void RemoveAt( int index )
345                         {
346                                 stct.RemoveAt( index );
347                         }
348
349                         /// <summary>
350                         /// コマンド入力に成功しているか調べる
351                         /// </summary>
352                         /// <param name="_ePad">入力が成功したか調べたいコマンド</param>
353                         /// <param name="_eInst">対象楽器</param>
354                         /// <returns>コマンド入力成功時true</returns>
355                         public bool CheckCommand( EパッドFlag[] _ePad, E楽器パート _eInst)
356                         {
357                                 int targetCount = _ePad.Length;
358                                 int stciCount = stct.Count;
359                                 if ( stciCount < targetCount )
360                                 {
361 //Debug.WriteLine("NOT start checking...stciCount=" + stciCount + ", targetCount=" + targetCount);
362                                         return false;
363                                 }
364
365                                 long curTime = CDTXMania.Timer.n現在時刻;
366 //Debug.WriteLine("Start checking...targetCount=" + targetCount);
367                                 for ( int i = targetCount - 1, j = stciCount - 1; i >= 0; i--, j-- )
368                                 {
369                                         if ( _ePad[ i ] != stct[ j ].ePad )
370                                         {
371 //Debug.WriteLine( "CMD解析: false targetCount=" + targetCount + ", i=" + i + ", j=" + j + ": ePad[]=" + _ePad[i] + ", stci[j] = " + stct[j].ePad );
372                                                 return false;
373                                         }
374                                         if ( stct[ j ].eInst != _eInst )
375                                         {
376 //Debug.WriteLine( "CMD解析: false " + i );
377                                                 return false;
378                                         }
379                                         if ( curTime - stct[ j ].time > 500 )
380                                         {
381 //Debug.WriteLine( "CMD解析: false " + i + "; over 500ms" );
382                                                 return false;
383                                         }
384                                         curTime = stct[ j ].time;
385                                 }
386
387 //Debug.Write( "CMD解析: 成功!(" + _ePad.Length + ") " );
388 //for ( int i = 0; i < _ePad.Length; i++ ) Debug.Write( _ePad[ i ] + ", " );
389 //Debug.WriteLine( "" );
390                                 //stct.RemoveRange( 0, targetCount );                   // #24396 2011.2.13 yyagi 
391                                 stct.Clear();                                                                   // #24396 2011.2.13 yyagi Clear all command input history in case you succeeded inputting some command
392
393                                 return true;
394                         }
395                 }
396                 protected CCommandHistory CommandHistory;
397
398                 protected void tカーソルを下へ移動する()
399                 {
400                         CDTXMania.Skin.soundカーソル移動音.t再生する();
401                         this.act曲リスト.t次に移動();
402                 }
403                 protected void tカーソルを上へ移動する()
404                 {
405                         CDTXMania.Skin.soundカーソル移動音.t再生する();
406                         this.act曲リスト.t前に移動();
407                 }
408                 protected void t曲をランダム選択する()
409                 {
410                         C曲リストノード song = this.act曲リスト.r現在選択中の曲;
411                         if( ( song.stackランダム演奏番号.Count == 0 ) || ( song.listランダム用ノードリスト == null ) )
412                         {
413                                 if( song.listランダム用ノードリスト == null )
414                                 {
415                                         song.listランダム用ノードリスト = this.t指定された曲が存在する場所の曲を列挙する_子リスト含む( song );
416                                 }
417                                 int count = song.listランダム用ノードリスト.Count;
418                                 if( count == 0 )
419                                 {
420                                         return;
421                                 }
422                                 int[] numArray = new int[ count ];
423                                 for( int i = 0; i < count; i++ )
424                                 {
425                                         numArray[ i ] = i;
426                                 }
427                                 for( int j = 0; j < ( count * 1.5 ); j++ )
428                                 {
429                                         int index = CDTXMania.Random.Next( count );
430                                         int num5 = CDTXMania.Random.Next( count );
431                                         int num6 = numArray[ num5 ];
432                                         numArray[ num5 ] = numArray[ index ];
433                                         numArray[ index ] = num6;
434                                 }
435                                 for( int k = 0; k < count; k++ )
436                                 {
437                                         song.stackランダム演奏番号.Push( numArray[ k ] );
438                                 }
439                                 if( CDTXMania.ConfigIni.bLogDTX詳細ログ出力 )
440                                 {
441                                         StringBuilder builder = new StringBuilder( 1024 );
442                                         builder.Append( string.Format( "ランダムインデックスリストを作成しました: {0}曲: ", song.stackランダム演奏番号.Count ) );
443                                         for( int m = 0; m < count; m++ )
444                                         {
445                                                 builder.Append( string.Format( "{0} ", numArray[ m ] ) );
446                                         }
447                                         Trace.TraceInformation( builder.ToString() );
448                                 }
449                         }
450                         this.r確定された曲 = song.listランダム用ノードリスト[ song.stackランダム演奏番号.Pop() ];
451                         this.n確定された曲の難易度 = this.act曲リスト.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( this.r確定された曲 );
452                         this.r確定されたスコア = this.r確定された曲.arスコア[ this.n確定された曲の難易度 ];
453                         this.eフェードアウト完了時の戻り値 = E戻り値.選曲した;
454                 //      this.actFOtoNowLoading.tフェードアウト開始();                                  // #27787 2012.3.10 yyagi 曲決定時の画面フェードアウトの省略
455 #if animetest
456             base.eフェーズID = CStage.Eフェーズ.選曲_決定演出;
457 #else
458                         base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
459 #endif
460                         if( CDTXMania.ConfigIni.bLogDTX詳細ログ出力 )
461                         {
462                                 int[] numArray2 = song.stackランダム演奏番号.ToArray();
463                                 StringBuilder builder2 = new StringBuilder( 0x400 );
464                                 builder2.Append( "ランダムインデックスリスト残り: " );
465                                 if( numArray2.Length > 0 )
466                                 {
467                                         for( int n = 0; n < numArray2.Length; n++ )
468                                         {
469                                                 builder2.Append( string.Format( "{0} ", numArray2[ n ] ) );
470                                         }
471                                 }
472                                 else
473                                 {
474                                         builder2.Append( "(なし)" );
475                                 }
476                                 Trace.TraceInformation( builder2.ToString() );
477                         }
478                         CDTXMania.Skin.bgm選曲画面.t停止する();
479                 }
480                 protected void t曲を選択する()
481                 {
482                         this.r確定された曲 = this.act曲リスト.r現在選択中の曲;
483                         this.r確定されたスコア = this.act曲リスト.r現在選択中のスコア;
484                         this.n確定された曲の難易度 = this.act曲リスト.n現在選択中の曲の現在の難易度レベル;
485                         if( ( this.r確定された曲 != null ) && ( this.r確定されたスコア != null ) )
486                         {
487                                 this.eフェードアウト完了時の戻り値 = E戻り値.選曲した;
488                         //      this.actFOtoNowLoading.tフェードアウト開始();                          // #27787 2012.3.10 yyagi 曲決定時の画面フェードアウトの省略
489                 if( CDTXMania.bXGRelease )
490                 {
491 #if animetest
492                     base.eフェーズID = CStage.Eフェーズ.選曲_決定演出;
493 #else
494                     base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
495 #endif
496                 }
497                 else
498                 {
499                                 this.actFOtoNowLoading.tフェードアウト開始();
500                     base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
501                 }
502                         }
503                         CDTXMania.Skin.bgm選曲画面.t停止する();
504                 }
505         protected void t決定アニメーション()
506         {
507             //決定からの演出
508             if( this.b決定演出カウンタ使用中 )
509             {
510                 this.ct決定演出待機.t進行();
511                 if( this.ct決定演出待機.b終了値に達した )
512                 {
513                     this.ct決定演出待機.t停止();
514                     this.b決定演出カウンタ使用中 = false;
515                 }
516             }
517
518             if( base.eフェーズID == Eフェーズ.選曲_決定演出 )
519             {
520                 if( this.ct決定演出待機.b進行中 )
521                 {
522                     this.actPresound.tサウンド停止();
523                     //CDTXMania.act文字コンソール.tPrint( 0, 0, C文字コンソール.Eフォント種別.白, "MUSIC DECIDED." );
524                     //CDTXMania.act文字コンソール.tPrint( 0, 16, C文字コンソール.Eフォント種別.白, "PLEASE WAIT  " + this.ct決定演出待機.n現在の値.ToString() );
525                 }
526
527                 if( this.ct決定演出待機.b終了値に達した )
528                 {
529                     this.t決定アニメーション終了();
530                 }
531             }
532         }
533         protected void t決定アニメーション開始()
534         {
535             if( !this.b決定演出カウンタ使用中 )
536             {
537                 this.b決定演出カウンタ使用中 = true;
538                 this.ct決定演出待機 = new CCounter( 0, 6000, 1, CDTXMania.Timer );
539             }
540         }
541         protected void t決定アニメーション終了()
542         {
543             //アニメーション終了後の処理。
544             this.actFOtoNowLoading.tフェードアウト開始();
545             base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
546         }
547                 private List<C曲リストノード> t指定された曲が存在する場所の曲を列挙する_子リスト含む( C曲リストノード song )
548                 {
549                         List<C曲リストノード> list = new List<C曲リストノード>();
550                         song = song.r親ノード;
551                         if( ( song == null ) && ( CDTXMania.Songs管理.list曲ルート.Count > 0 ) )
552                         {
553                                 foreach( C曲リストノード c曲リストノード in CDTXMania.Songs管理.list曲ルート )
554                                 {
555                                         if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )
556                                         {
557                                                 list.Add( c曲リストノード );
558                                         }
559                                         if( ( c曲リストノード.list子リスト != null ) && CDTXMania.ConfigIni.bランダムセレクトで子BOXを検索対象とする )
560                                         {
561                                                 this.t指定された曲の子リストの曲を列挙する_孫リスト含む( c曲リストノード, ref list );
562                                         }
563                                 }
564                                 return list;
565                         }
566                         this.t指定された曲の子リストの曲を列挙する_孫リスト含む( song, ref list );
567                         return list;
568                 }
569                 private void t指定された曲の子リストの曲を列挙する_孫リスト含む( C曲リストノード r親, ref List<C曲リストノード> list )
570                 {
571                         if( ( r親 != null ) && ( r親.list子リスト != null ) )
572                         {
573                                 foreach( C曲リストノード c曲リストノード in r親.list子リスト )
574                                 {
575                                         if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )
576                                         {
577                                                 list.Add( c曲リストノード );
578                                         }
579                                         if( ( c曲リストノード.list子リスト != null ) && CDTXMania.ConfigIni.bランダムセレクトで子BOXを検索対象とする )
580                                         {
581                                                 this.t指定された曲の子リストの曲を列挙する_孫リスト含む( c曲リストノード, ref list );
582                                         }
583                                 }
584                         }
585                 }
586                 //-----------------
587                 #endregion
588         }
589 }