2 using System.Collections.Generic;
\r
4 using System.Diagnostics;
\r
5 using System.Threading;
\r
8 using System.Runtime.Serialization.Formatters.Binary;
\r
13 internal class CStage起動 : CStage
\r
19 base.eステージID = CStage.Eステージ.起動;
\r
20 base.b活性化してない = true;
\r
26 public override void On活性化()
\r
28 Trace.TraceInformation( "起動ステージを活性化します。" );
\r
32 this.list進行文字列 = new List<string>();
\r
33 base.eフェーズID = CStage.Eフェーズ.共通_通常状態;
\r
35 Trace.TraceInformation( "起動ステージの活性化を完了しました。" );
\r
42 public override void On非活性化()
\r
44 Trace.TraceInformation( "起動ステージを非活性化します。" );
\r
48 this.list進行文字列 = null;
\r
49 if( ( this.thリスト構築 != null ) && this.thリスト構築.IsAlive )
\r
51 Trace.TraceWarning( "リスト構築スレッドを強制停止します。" );
\r
52 this.thリスト構築.Abort();
\r
53 this.thリスト構築.Join();
\r
56 Trace.TraceInformation( "起動ステージの非活性化を完了しました。" );
\r
63 public override void OnManagedリソースの作成()
\r
65 if( !base.b活性化してない )
\r
67 this.tx背景 = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSetup background.jpg" ), false );
\r
68 base.OnManagedリソースの作成();
\r
71 public override void OnManagedリソースの解放()
\r
73 if( !base.b活性化してない )
\r
75 CDTXMania.tテクスチャの解放( ref this.tx背景 );
\r
76 base.OnManagedリソースの解放();
\r
79 public override int On進行描画()
\r
81 if( !base.b活性化してない )
\r
83 if( base.b初めての進行描画 )
\r
85 this.list進行文字列.Add( "DTXMania powered by YAMAHA Silent Session Drums\n" );
\r
86 this.list進行文字列.Add( "Release: " + CDTXMania.VERSION + " [" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + "]" );
\r
87 this.thリスト構築 = new Thread( new ThreadStart( this.t曲リストの構築 ) );
\r
88 this.thリスト構築.Name = "曲リストの構築";
\r
89 this.thリスト構築.IsBackground = true;
\r
90 this.thリスト構築.Start();
\r
91 base.b初めての進行描画 = false;
\r
95 CSongs管理 s管理 = CDTXMania.Songs管理;
\r
97 if( this.tx背景 != null )
\r
98 this.tx背景.t2D描画( CDTXMania.app.Device, 0, 0 );
\r
100 #region [ this.str現在進行中 の決定 ]
\r
101 //-----------------
\r
102 switch( base.eフェーズID )
\r
104 case CStage.Eフェーズ.起動0_システムサウンドを構築:
\r
105 this.str現在進行中 = "Loading system sounds ... ";
\r
108 case CStage.Eフェーズ.起動1_SongsDBからスコアキャッシュを構築:
\r
109 this.str現在進行中 = "Loading songs.db ... ";
\r
112 case CStage.Eフェーズ.起動2_曲を検索してリストを作成する:
\r
113 this.str現在進行中 = string.Format( "{0} ... {1}", "Enumerating songs", s管理.n検索されたスコア数 );
\r
116 case CStage.Eフェーズ.起動3_スコアキャッシュをリストに反映する:
\r
117 this.str現在進行中 = string.Format( "{0} ... {1}/{2}", "Loading score properties from songs.db", CDTXMania.Songs管理.nスコアキャッシュから反映できたスコア数, s管理.n検索されたスコア数 );
\r
120 case CStage.Eフェーズ.起動4_スコアキャッシュになかった曲をファイルから読み込んで反映する:
\r
121 this.str現在進行中 = string.Format( "{0} ... {1}/{2}", "Loading score properties from files", CDTXMania.Songs管理.nファイルから反映できたスコア数, CDTXMania.Songs管理.n検索されたスコア数 - s管理.nスコアキャッシュから反映できたスコア数 );
\r
124 case CStage.Eフェーズ.起動5_曲リストへ後処理を適用する:
\r
125 this.str現在進行中 = string.Format( "{0} ... ", "Building songlists" );
\r
128 case CStage.Eフェーズ.起動6_スコアキャッシュをSongsDBに出力する:
\r
129 this.str現在進行中 = string.Format( "{0} ... ", "Saving songs.db" );
\r
132 case CStage.Eフェーズ.起動7_完了:
\r
133 this.str現在進行中 = "Setup done.";
\r
136 //-----------------
\r
138 #region [ this.list進行文字列+this.現在進行中 の表示 ]
\r
139 //-----------------
\r
140 lock( this.list進行文字列 )
\r
144 foreach( string str in this.list進行文字列 )
\r
146 CDTXMania.act文字コンソール.tPrint( x, y, C文字コンソール.Eフォント種別.灰細, str );
\r
149 CDTXMania.act文字コンソール.tPrint( x, y, C文字コンソール.Eフォント種別.灰細, this.str現在進行中 );
\r
151 //-----------------
\r
154 if( !this.thリスト構築.IsAlive )
\r
165 #region [ private ]
\r
166 //-----------------
\r
167 private List<string> list進行文字列;
\r
168 private const string MSG進行0 = "Loading system sounds";
\r
169 private const string MSG進行1 = "Loading songs.db";
\r
170 private const string MSG進行2 = "Enumerating songs";
\r
171 private const string MSG進行3 = "Loading score properties from songs.db";
\r
172 private const string MSG進行4 = "Loading score properties from files";
\r
173 private const string MSG進行5 = "Loading score properties from socre.ini";
\r
174 private const string MSG進行6 = "Building songlists";
\r
175 private const string MSG進行7 = "Saving songs.db";
\r
176 private string str現在進行中 = "";
\r
177 private Thread thリスト構築;
\r
178 private CTexture tx背景;
\r
180 private void t曲リストの構築()
\r
183 // 本メソッドは別スレッドで動作するが、プラグイン側でカレントディレクトリを変更しても大丈夫なように、
\r
184 // すべてのファイルアクセスは「絶対パス」で行うこと。(2010.9.16)
\r
186 DateTime now = DateTime.Now;
\r
187 string str = CDTXMania.strEXEのあるフォルダ + "songs.db";
\r
188 string strPathSongsDB2 = CDTXMania.strEXEのあるフォルダ + "songs2.db";
\r
189 bool bIsFastBoot = false;
\r
190 bool bCanFastBoot = false;
\r
191 bool bSucceededFastBoot = false;
\r
193 Microsoft.VisualBasic.Devices.Keyboard key = new Microsoft.VisualBasic.Devices.Keyboard();
\r
194 if ( key.CapsLock ) // #27060 2012.1.26 yyagi CapsLock=ONのときは読み込み高速化
\r
196 bIsFastBoot = true;
\r
198 if ( File.Exists( strPathSongsDB2 ) )
\r
200 bCanFastBoot = true;
\r
205 #region [ 0) システムサウンドの構築 ]
\r
206 //-----------------------------
\r
207 base.eフェーズID = CStage.Eフェーズ.起動0_システムサウンドを構築;
\r
209 Trace.TraceInformation( "0) システムサウンドを構築します。" );
\r
214 for( int i = 0; i < CDTXMania.Skin.nシステムサウンド数; i++ )
\r
216 CSkin.Cシステムサウンド cシステムサウンド = CDTXMania.Skin[ i ];
\r
217 if( !CDTXMania.bコンパクトモード || cシステムサウンド.bCompact対象 )
\r
222 Trace.TraceInformation( "システムサウンドを読み込みました。({0})", new object[] { cシステムサウンド.strファイル名 } );
\r
223 if( ( cシステムサウンド == CDTXMania.Skin.bgm起動画面 ) && cシステムサウンド.b読み込み成功 )
\r
228 catch( FileNotFoundException )
\r
230 Trace.TraceWarning( "システムサウンドが存在しません。({0})", new object[] { cシステムサウンド.strファイル名 } );
\r
232 catch( Exception exception )
\r
234 Trace.TraceError( exception.Message );
\r
235 Trace.TraceWarning( "システムサウンドの読み込みに失敗しました。({0})", new object[] { cシステムサウンド.strファイル名 } );
\r
239 lock( this.list進行文字列 )
\r
241 this.list進行文字列.Add( "Loading system sounds ... OK " );
\r
248 //-----------------------------
\r
251 if( CDTXMania.bコンパクトモード )
\r
253 Trace.TraceInformation( "コンパクトモードなので残りの起動処理は省略します。" );
\r
257 #region [ 1) songs.db の読み込み ]
\r
258 //-----------------------------
\r
259 base.eフェーズID = CStage.Eフェーズ.起動1_SongsDBからスコアキャッシュを構築;
\r
261 Trace.TraceInformation( "1) songs.db を読み込みます。" );
\r
266 if( !CDTXMania.ConfigIni.bConfigIniがないかDTXManiaのバージョンが異なる )
\r
270 CDTXMania.Songs管理.tSongsDBを読み込む( str );
\r
274 Trace.TraceError( "songs.db の読み込みに失敗しました。" );
\r
276 Trace.TraceInformation( "songs.db の読み込みを完了しました。[{0}スコア]", new object[] { CDTXMania.Songs管理.nSongsDBから取得できたスコア数 } );
\r
277 lock( this.list進行文字列 )
\r
279 this.list進行文字列.Add( "Loading songs.db ... OK" );
\r
284 bIsFastBoot = false;
\r
285 Trace.TraceInformation( "初回の起動であるかまたはDTXManiaのバージョンが上がったため、songs.db の読み込みをスキップします。" );
\r
286 lock( this.list進行文字列 )
\r
288 this.list進行文字列.Add( "Loading songs.db ... Skip" );
\r
296 //-----------------------------
\r
299 if ( bIsFastBoot && bCanFastBoot ) // #27060 2012.1.26 yyagi
\r
301 Trace.TraceInformation( "2') 曲の検索を止めて、読込を高速化します。" );
\r
303 // byte[] buf = File.ReadAllBytes( strPathSongsDB2 ); // 一旦メモリにまとめ読みしてからdeserializeした方が高速かと思ったら全く変わらなかったので削除
\r
304 // using ( MemoryStream input = new MemoryStream(buf, false) )
\r
305 using ( Stream input = File.OpenRead( strPathSongsDB2 ) )
\r
309 BinaryFormatter formatter = new BinaryFormatter();
\r
310 CDTXMania.Songs管理 = (CSongs管理) formatter.Deserialize( input );
\r
311 bSucceededFastBoot = true;
\r
313 catch ( Exception )
\r
315 bCanFastBoot = false; // deserialize失敗時は、通常通り曲データ検索を行う
\r
319 if ( !bSucceededFastBoot )
\r
321 bCanFastBoot = false; // 曲データの検索をしたのなら、後で高速起動用にsongs2.dbの書き出しをしておく
\r
322 #region [ 2) 曲データの検索 ]
\r
323 //-----------------------------
\r
324 base.eフェーズID = CStage.Eフェーズ.起動2_曲を検索してリストを作成する;
\r
326 Trace.TraceInformation( "2) 曲データを検索します。" );
\r
331 if ( !string.IsNullOrEmpty( CDTXMania.ConfigIni.str曲データ検索パス ) )
\r
333 string[] strArray = CDTXMania.ConfigIni.str曲データ検索パス.Split( new char[] { ';' } );
\r
334 if ( strArray.Length > 0 )
\r
337 foreach ( string str2 in strArray )
\r
339 string path = str2;
\r
340 if ( !Path.IsPathRooted( path ) )
\r
342 path = CDTXMania.strEXEのあるフォルダ + str2; // 相対パスの場合、絶対パスに直す(2010.9.16)
\r
345 if ( !string.IsNullOrEmpty( path ) )
\r
347 Trace.TraceInformation( "検索パス: " + path );
\r
352 CDTXMania.Songs管理.t曲を検索してリストを作成する( path, true );
\r
354 catch ( Exception exception2 )
\r
356 Trace.TraceError( exception2.Message );
\r
357 Trace.TraceError( exception2.StackTrace );
\r
358 Trace.TraceError( "例外が発生しましたが処理を継続します。" );
\r
370 Trace.TraceWarning( "曲データの検索パス(DTXPath)の指定がありません。" );
\r
375 Trace.TraceInformation( "曲データの検索を完了しました。[{0}曲{1}スコア]", new object[] { CDTXMania.Songs管理.n検索された曲ノード数, CDTXMania.Songs管理.n検索されたスコア数 } );
\r
378 lock ( this.list進行文字列 )
\r
380 this.list進行文字列.Add( string.Format( "{0} ... {1} scores ({2} songs)", "Enumerating songs", CDTXMania.Songs管理.n検索されたスコア数, CDTXMania.Songs管理.n検索された曲ノード数 ) );
\r
382 //-----------------------------
\r
384 #region [ 3) songs.db 情報の曲リストへの反映 ]
\r
385 //-----------------------------
\r
386 base.eフェーズID = CStage.Eフェーズ.起動3_スコアキャッシュをリストに反映する;
\r
388 Trace.TraceInformation( "3) songs.db の情報を曲リストへ反映します。" );
\r
393 CDTXMania.Songs管理.tスコアキャッシュを曲リストに反映する();
\r
395 catch( Exception exception3 )
\r
397 Trace.TraceError( exception3.Message );
\r
398 Trace.TraceError( exception3.StackTrace );
\r
399 Trace.TraceError( "例外が発生しましたが処理を継続します。" );
\r
403 Trace.TraceInformation( "曲リストへの反映を完了しました。[{0}/{1}スコア]", new object[] { CDTXMania.Songs管理.nスコアキャッシュから反映できたスコア数, CDTXMania.Songs管理.n検索されたスコア数 } );
\r
406 lock( this.list進行文字列 )
\r
408 this.list進行文字列.Add( string.Format( "{0} ... {1}/{2}", "Loading score properties from songs.db", CDTXMania.Songs管理.nスコアキャッシュから反映できたスコア数, CDTXMania.Songs管理.n検索されたスコア数 ) );
\r
410 //-----------------------------
\r
412 #region [ 4) songs.db になかった曲データをファイルから読み込んで反映 ]
\r
413 //-----------------------------
\r
414 base.eフェーズID = CStage.Eフェーズ.起動4_スコアキャッシュになかった曲をファイルから読み込んで反映する;
\r
416 int num2 = CDTXMania.Songs管理.n検索されたスコア数 - CDTXMania.Songs管理.nスコアキャッシュから反映できたスコア数;
\r
417 Trace.TraceInformation( "{0}, {1}", CDTXMania.Songs管理.n検索されたスコア数, CDTXMania.Songs管理.nスコアキャッシュから反映できたスコア数 );
\r
419 Trace.TraceInformation( "4) songs.db になかった曲データ[{0}スコア]の情報をファイルから読み込んで反映します。", new object[] { num2 } );
\r
424 CDTXMania.Songs管理.tSongsDBになかった曲をファイルから読み込んで反映する();
\r
426 catch( Exception exception4 )
\r
428 Trace.TraceError( exception4.Message );
\r
429 Trace.TraceError( exception4.StackTrace );
\r
430 Trace.TraceError( "例外が発生しましたが処理を継続します。" );
\r
434 Trace.TraceInformation( "曲データへの反映を完了しました。[{0}/{1}スコア]", new object[] { CDTXMania.Songs管理.nファイルから反映できたスコア数, num2 } );
\r
437 lock( this.list進行文字列 )
\r
439 this.list進行文字列.Add( string.Format( "{0} ... {1}/{2}", "Loading score properties from files", CDTXMania.Songs管理.nファイルから反映できたスコア数, CDTXMania.Songs管理.n検索されたスコア数 - CDTXMania.Songs管理.nスコアキャッシュから反映できたスコア数 ) );
\r
441 //-----------------------------
\r
443 #region [ 5) 曲リストへの後処理の適用 ]
\r
444 //-----------------------------
\r
445 base.eフェーズID = CStage.Eフェーズ.起動5_曲リストへ後処理を適用する;
\r
447 Trace.TraceInformation( "5) 曲リストへの後処理を適用します。" );
\r
452 CDTXMania.Songs管理.t曲リストへ後処理を適用する();
\r
454 catch( Exception exception5 )
\r
456 Trace.TraceError( exception5.Message );
\r
457 Trace.TraceError( exception5.StackTrace );
\r
458 Trace.TraceError( "例外が発生しましたが処理を継続します。" );
\r
462 Trace.TraceInformation( "曲リストへの後処理を完了しました。" );
\r
465 lock( this.list進行文字列 )
\r
467 this.list進行文字列.Add( string.Format( "{0} ... OK", "Building songlists" ) );
\r
469 //-----------------------------
\r
471 #region [ 6) songs.db への保存 ]
\r
472 //-----------------------------
\r
473 base.eフェーズID = CStage.Eフェーズ.起動6_スコアキャッシュをSongsDBに出力する;
\r
475 Trace.TraceInformation( "6) 曲データの情報を songs.db へ出力します。" );
\r
480 CDTXMania.Songs管理.tスコアキャッシュをSongsDBに出力する( str );
\r
482 catch( Exception exception6 )
\r
484 Trace.TraceError( exception6.Message );
\r
485 Trace.TraceError( exception6.StackTrace );
\r
486 Trace.TraceError( "例外が発生しましたが処理を継続します。" );
\r
490 Trace.TraceInformation( "songs.db への出力を完了しました。[{0}スコア]", new object[] { CDTXMania.Songs管理.nSongsDBへ出力できたスコア数 } );
\r
493 lock( this.list進行文字列 )
\r
495 this.list進行文字列.Add( string.Format( "{0} ... OK", "Saving songs.db" ) );
\r
501 #region [ 7) songs2.db への保存 ] // #27060 2012.1.26 yyagi
\r
502 // シリアライズ動作が遅いため、別スレッドで動かして起動を高速化する
\r
503 // ただし別スレッドに投げた後のフォローは一切していないので注意 (処理時間は3000曲で0.5秒くらいなのでこのままでも大丈夫だとは思いますが)
\r
504 Thread t = new Thread( new ParameterizedThreadStart( SerializeSongsDB2 ) );
\r
505 t.Start( strPathSongsDB2 );
\r
506 // SerializeSongsDB2( strPathSongsDB2 );
\r
507 //-----------------------------
\r
514 base.eフェーズID = CStage.Eフェーズ.起動7_完了;
\r
515 TimeSpan span = (TimeSpan) ( DateTime.Now - now );
\r
516 Trace.TraceInformation( "起動所要時間: {0}", new object[] { span.ToString() } );
\r
519 //-----------------
\r
525 /// <param name="o">songs2.dbのファイル名(絶対パス)</param>
\r
526 private static void SerializeSongsDB2(object o)
\r
528 string strPathSongsDB2 = (string) o;
\r
529 bool bSucceededSerialize = true;
\r
530 Stream output = null;
\r
533 output = File.Create( strPathSongsDB2 );
\r
534 BinaryFormatter formatter = new BinaryFormatter();
\r
535 formatter.Serialize( output, CDTXMania.Songs管理 );
\r
537 catch ( Exception )
\r
539 bSucceededSerialize = false;
\r
544 if ( !bSucceededSerialize )
\r
548 File.Delete( strPathSongsDB2 ); // serializeに失敗したら、songs2.dbファイルを消しておく
\r
550 catch ( Exception )
\r