2 using System.Collections.Generic;
4 using System.Runtime.InteropServices;
6 using System.Diagnostics;
12 internal class CStage選曲 : CStage
15 public int nスクロールバー相対y座標
19 if ( act曲リスト != null )
21 return act曲リスト.nスクロールバー相対y座標;
29 public bool bIsEnumeratingSongs
33 return act曲リスト.bIsEnumeratingSongs;
37 act曲リスト.bIsEnumeratingSongs = value;
44 return this.act曲リスト.bスクロール中;
47 public int n確定された曲の難易度
57 public C曲リストノード r確定された曲
62 public int n現在選択中の曲の難易度
66 return this.act曲リスト.n現在選択中の曲の現在の難易度レベル;
69 public Cスコア r現在選択中のスコア
73 return this.act曲リスト.r現在選択中のスコア;
76 public C曲リストノード r現在選択中の曲
80 return this.act曲リスト.r現在選択中の曲;
87 base.eステージID = CStage.Eステージ.選曲;
88 base.eフェーズID = CStage.Eフェーズ.共通_通常状態;
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() );
104 this.CommandHistory = new CCommandHistory(); // #24063 2011.1.16 yyagi
110 public void t選択曲変更通知()
112 this.actPresound.t選択曲が変更された();
113 this.act演奏履歴パネル.t選択曲が変更された();
114 this.actステータスパネル.t選択曲が変更された();
115 this.actArtistComment.t選択曲が変更された();
117 #region [ プラグインにも通知する(BOX, RANDOM, BACK なら通知しない)]
118 //---------------------
119 if( CDTXMania.app != null )
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現在選択中のスコア;
127 c曲リストノード = CDTXMania.stage選曲GITADORA.r現在選択中の曲;
128 cスコア = CDTXMania.stage選曲GITADORA.r現在選択中のスコア;
131 if( c曲リストノード != null && cスコア != null && c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )
133 string str選択曲ファイル名 = cスコア.ファイル情報.ファイルの絶対パス;
134 CSetDef setDef = null;
135 int nブロック番号inSetDef = -1;
138 if( !string.IsNullOrEmpty( c曲リストノード.pathSetDefの絶対パス ) && File.Exists( c曲リストノード.pathSetDefの絶対パス ) )
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曲リストノード );
146 foreach( CDTXMania.STPlugin stPlugin in CDTXMania.app.listプラグイン )
148 Directory.SetCurrentDirectory( stPlugin.strプラグインフォルダ );
149 stPlugin.plugin.On選択曲変更( str選択曲ファイル名, setDef, nブロック番号inSetDef, n曲番号inブロック );
150 Directory.SetCurrentDirectory( CDTXMania.strEXEのあるフォルダ );
154 //---------------------
163 /// <param name="cs"></param>
164 public void Refresh( CSongs管理 cs, bool bRemakeSongTitleBar)
166 this.act曲リスト.Refresh( cs, bRemakeSongTitleBar );
169 public override void On活性化()
171 Trace.TraceInformation( "選曲ステージを活性化します。" );
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;
183 this.actステータスパネル.t選択曲が変更された(); // 最大ランクを更新
187 Trace.TraceInformation( "選曲ステージの活性化を完了しました。" );
191 public override void On非活性化()
193 Trace.TraceInformation( "選曲ステージを非活性化します。" );
197 for( int i = 0; i < 4; i++ )
199 this.ctキー反復用[ i ] = null;
201 this.ct決定演出待機 = null;
206 Trace.TraceInformation( "選曲ステージの非活性化を完了しました。" );
210 public override void OnManagedリソースの作成()
214 public override void OnManagedリソースの解放()
219 public enum E戻り値 : int
234 [StructLayout( LayoutKind.Sequential )]
235 protected struct STキー反復用カウンタ
238 public CCounter Down;
241 public CCounter this[ int index ]
259 throw new IndexOutOfRangeException();
281 throw new IndexOutOfRangeException();
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;
297 protected CActSortSongs actSortSongs;
298 protected CActSelectQuickConfig actQuickConfig;
300 protected bool bBGM再生済み;
301 protected STキー反復用カウンタ ctキー反復用;
302 public CCounter ct登場時アニメ用共通;
303 public CCounter ct決定演出待機; //テスト
304 protected bool b決定演出カウンタ使用中;
305 protected E戻り値 eフェードアウト完了時の戻り値;
308 protected struct STCommandTime // #24063 2011.1.16 yyagi コマンド入力時刻の記録用
310 public E楽器パート eInst; // 使用楽器
311 public EパッドFlag ePad; // 押されたコマンド(同時押しはOR演算で列挙する)
312 public long time; // コマンド入力時刻
314 protected class CCommandHistory // #24063 2011.1.16 yyagi コマンド入力履歴を保持・確認するクラス
316 readonly int buffersize = 16;
317 private List<STCommandTime> stct;
319 public CCommandHistory() // コンストラクタ
321 stct = new List<STCommandTime>( buffersize );
327 /// <param name="_eInst">楽器の種類</param>
328 /// <param name="_ePad">入力コマンド(同時押しはOR演算で列挙すること)</param>
329 public void Add( E楽器パート _eInst, EパッドFlag _ePad )
331 STCommandTime _stct = new STCommandTime {
334 time = CDTXMania.Timer.n現在時刻
337 if ( stct.Count >= buffersize )
342 //Debug.WriteLine( "CMDHIS: 楽器=" + _stct.eInst + ", CMD=" + _stct.ePad + ", time=" + _stct.time );
344 public void RemoveAt( int index )
346 stct.RemoveAt( index );
350 /// コマンド入力に成功しているか調べる
352 /// <param name="_ePad">入力が成功したか調べたいコマンド</param>
353 /// <param name="_eInst">対象楽器</param>
354 /// <returns>コマンド入力成功時true</returns>
355 public bool CheckCommand( EパッドFlag[] _ePad, E楽器パート _eInst)
357 int targetCount = _ePad.Length;
358 int stciCount = stct.Count;
359 if ( stciCount < targetCount )
361 //Debug.WriteLine("NOT start checking...stciCount=" + stciCount + ", targetCount=" + targetCount);
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-- )
369 if ( _ePad[ i ] != stct[ j ].ePad )
371 //Debug.WriteLine( "CMD解析: false targetCount=" + targetCount + ", i=" + i + ", j=" + j + ": ePad[]=" + _ePad[i] + ", stci[j] = " + stct[j].ePad );
374 if ( stct[ j ].eInst != _eInst )
376 //Debug.WriteLine( "CMD解析: false " + i );
379 if ( curTime - stct[ j ].time > 500 )
381 //Debug.WriteLine( "CMD解析: false " + i + "; over 500ms" );
384 curTime = stct[ j ].time;
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
396 protected CCommandHistory CommandHistory;
398 protected void tカーソルを下へ移動する()
400 CDTXMania.Skin.soundカーソル移動音.t再生する();
401 this.act曲リスト.t次に移動();
403 protected void tカーソルを上へ移動する()
405 CDTXMania.Skin.soundカーソル移動音.t再生する();
406 this.act曲リスト.t前に移動();
408 protected void t曲をランダム選択する()
410 C曲リストノード song = this.act曲リスト.r現在選択中の曲;
411 if( ( song.stackランダム演奏番号.Count == 0 ) || ( song.listランダム用ノードリスト == null ) )
413 if( song.listランダム用ノードリスト == null )
415 song.listランダム用ノードリスト = this.t指定された曲が存在する場所の曲を列挙する_子リスト含む( song );
417 int count = song.listランダム用ノードリスト.Count;
422 int[] numArray = new int[ count ];
423 for( int i = 0; i < count; i++ )
427 for( int j = 0; j < ( count * 1.5 ); j++ )
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;
435 for( int k = 0; k < count; k++ )
437 song.stackランダム演奏番号.Push( numArray[ k ] );
439 if( CDTXMania.ConfigIni.bLogDTX詳細ログ出力 )
441 StringBuilder builder = new StringBuilder( 1024 );
442 builder.Append( string.Format( "ランダムインデックスリストを作成しました: {0}曲: ", song.stackランダム演奏番号.Count ) );
443 for( int m = 0; m < count; m++ )
445 builder.Append( string.Format( "{0} ", numArray[ m ] ) );
447 Trace.TraceInformation( builder.ToString() );
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 曲決定時の画面フェードアウトの省略
456 base.eフェーズID = CStage.Eフェーズ.選曲_決定演出;
458 base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
460 if( CDTXMania.ConfigIni.bLogDTX詳細ログ出力 )
462 int[] numArray2 = song.stackランダム演奏番号.ToArray();
463 StringBuilder builder2 = new StringBuilder( 0x400 );
464 builder2.Append( "ランダムインデックスリスト残り: " );
465 if( numArray2.Length > 0 )
467 for( int n = 0; n < numArray2.Length; n++ )
469 builder2.Append( string.Format( "{0} ", numArray2[ n ] ) );
474 builder2.Append( "(なし)" );
476 Trace.TraceInformation( builder2.ToString() );
478 CDTXMania.Skin.bgm選曲画面.t停止する();
480 protected void t曲を選択する()
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 ) )
487 this.eフェードアウト完了時の戻り値 = E戻り値.選曲した;
488 // this.actFOtoNowLoading.tフェードアウト開始(); // #27787 2012.3.10 yyagi 曲決定時の画面フェードアウトの省略
489 if( CDTXMania.bXGRelease )
492 base.eフェーズID = CStage.Eフェーズ.選曲_決定演出;
494 base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
499 this.actFOtoNowLoading.tフェードアウト開始();
500 base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
503 CDTXMania.Skin.bgm選曲画面.t停止する();
505 protected void t決定アニメーション()
508 if( this.b決定演出カウンタ使用中 )
511 if( this.ct決定演出待機.b終了値に達した )
514 this.b決定演出カウンタ使用中 = false;
518 if( base.eフェーズID == Eフェーズ.選曲_決定演出 )
520 if( this.ct決定演出待機.b進行中 )
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() );
527 if( this.ct決定演出待機.b終了値に達した )
533 protected void t決定アニメーション開始()
535 if( !this.b決定演出カウンタ使用中 )
537 this.b決定演出カウンタ使用中 = true;
538 this.ct決定演出待機 = new CCounter( 0, 6000, 1, CDTXMania.Timer );
541 protected void t決定アニメーション終了()
544 this.actFOtoNowLoading.tフェードアウト開始();
545 base.eフェーズID = CStage.Eフェーズ.選曲_NowLoading画面へのフェードアウト;
547 private List<C曲リストノード> t指定された曲が存在する場所の曲を列挙する_子リスト含む( C曲リストノード song )
549 List<C曲リストノード> list = new List<C曲リストノード>();
551 if( ( song == null ) && ( CDTXMania.Songs管理.list曲ルート.Count > 0 ) )
553 foreach( C曲リストノード c曲リストノード in CDTXMania.Songs管理.list曲ルート )
555 if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )
557 list.Add( c曲リストノード );
559 if( ( c曲リストノード.list子リスト != null ) && CDTXMania.ConfigIni.bランダムセレクトで子BOXを検索対象とする )
561 this.t指定された曲の子リストの曲を列挙する_孫リスト含む( c曲リストノード, ref list );
566 this.t指定された曲の子リストの曲を列挙する_孫リスト含む( song, ref list );
569 private void t指定された曲の子リストの曲を列挙する_孫リスト含む( C曲リストノード r親, ref List<C曲リストノード> list )
571 if( ( r親 != null ) && ( r親.list子リスト != null ) )
573 foreach( C曲リストノード c曲リストノード in r親.list子リスト )
575 if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )
577 list.Add( c曲リストノード );
579 if( ( c曲リストノード.list子リスト != null ) && CDTXMania.ConfigIni.bランダムセレクトで子BOXを検索対象とする )
581 this.t指定された曲の子リストの曲を列挙する_孫リスト含む( c曲リストノード, ref list );