OSDN Git Service

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