OSDN Git Service

#27648 デバッグメッセージの削除漏れ。
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / ステージ / 05.選曲 / CActSelect曲リスト.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Globalization;\r
5 using System.Runtime.InteropServices;\r
6 using System.Drawing;\r
7 using System.Drawing.Imaging;\r
8 using System.Diagnostics;\r
9 using SlimDX;\r
10 using FDK;\r
11 \r
12 namespace DTXMania\r
13 {\r
14         internal class CActSelect曲リスト : CActivity\r
15         {\r
16                 // プロパティ\r
17 \r
18                 public bool bIsEnumeratingSongs\r
19                 {\r
20                         get;\r
21                         set;\r
22                 }\r
23                 public bool bスクロール中\r
24                 {\r
25                         get\r
26                         {\r
27                                 if( this.n目標のスクロールカウンタ == 0 )\r
28                                 {\r
29                                         return ( this.n現在のスクロールカウンタ != 0 );\r
30                                 }\r
31                                 return true;\r
32                         }\r
33                 }\r
34                 public int n現在のアンカ難易度レベル \r
35                 {\r
36                         get;\r
37                         private set;\r
38                 }\r
39                 public int n現在選択中の曲の現在の難易度レベル\r
40                 {\r
41                         get\r
42                         {\r
43                                 return this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( this.r現在選択中の曲 );\r
44                         }\r
45                 }\r
46                 public Cスコア r現在選択中のスコア\r
47                 {\r
48                         get\r
49                         {\r
50                                 if( this.r現在選択中の曲 != null )\r
51                                 {\r
52                                         return this.r現在選択中の曲.arスコア[ this.n現在選択中の曲の現在の難易度レベル ];\r
53                                 }\r
54                                 return null;\r
55                         }\r
56                 }\r
57                 public C曲リストノード r現在選択中の曲 \r
58                 {\r
59                         get;\r
60                         private set;\r
61                 }\r
62 \r
63 \r
64                 // コンストラクタ\r
65 \r
66                 public CActSelect曲リスト()\r
67                 {\r
68                         this.r現在選択中の曲 = null;\r
69                         this.n現在のアンカ難易度レベル = 0;\r
70                         base.b活性化してない = true;\r
71                         this.bIsEnumeratingSongs = false;\r
72                 }\r
73 \r
74 \r
75                 // メソッド\r
76 \r
77                 public int n現在のアンカ難易度レベルに最も近い難易度レベルを返す( C曲リストノード song )\r
78                 {\r
79                         // 事前チェック。\r
80 \r
81                         if( song == null )\r
82                                 return this.n現在のアンカ難易度レベル;      // 曲がまったくないよ\r
83 \r
84                         if( song.arスコア[ this.n現在のアンカ難易度レベル ] != null )\r
85                                 return this.n現在のアンカ難易度レベル;      // 難易度ぴったりの曲があったよ\r
86 \r
87                         if( ( song.eノード種別 == C曲リストノード.Eノード種別.BOX ) || ( song.eノード種別 == C曲リストノード.Eノード種別.BACKBOX ) )\r
88                                 return 0;                                                               // BOX と BACKBOX は関係無いよ\r
89 \r
90 \r
91                         // 現在のアンカレベルから、難易度上向きに検索開始。\r
92 \r
93                         int n最も近いレベル = this.n現在のアンカ難易度レベル;\r
94 \r
95                         for( int i = 0; i < 5; i++ )\r
96                         {\r
97                                 if( song.arスコア[ n最も近いレベル ] != null )\r
98                                         break;  // 曲があった。\r
99 \r
100                                 n最も近いレベル = ( n最も近いレベル + 1 ) % 5;    // 曲がなかったので次の難易度レベルへGo。(5以上になったら0に戻る。)\r
101                         }\r
102 \r
103 \r
104                         // 見つかった曲がアンカより下のレベルだった場合……\r
105                         // アンカから下向きに検索すれば、もっとアンカに近い曲があるんじゃね?\r
106 \r
107                         if( n最も近いレベル < this.n現在のアンカ難易度レベル )\r
108                         {\r
109                                 // 現在のアンカレベルから、難易度下向きに検索開始。\r
110 \r
111                                 n最も近いレベル = this.n現在のアンカ難易度レベル;\r
112 \r
113                                 for( int i = 0; i < 5; i++ )\r
114                                 {\r
115                                         if( song.arスコア[ n最も近いレベル ] != null )\r
116                                                 break;  // 曲があった。\r
117 \r
118                                         n最も近いレベル = ( ( n最も近いレベル - 1 ) + 5 ) % 5;    // 曲がなかったので次の難易度レベルへGo。(0未満になったら4に戻る。)\r
119                                 }\r
120                         }\r
121 \r
122                         return n最も近いレベル;\r
123                 }\r
124                 public C曲リストノード r指定された曲が存在するリストの先頭の曲( C曲リストノード song )\r
125                 {\r
126                         List<C曲リストノード> songList = GetSongListWithinMe( song );\r
127                         return ( songList == null ) ? null : songList[ 0 ];\r
128                 }\r
129                 public C曲リストノード r指定された曲が存在するリストの末尾の曲( C曲リストノード song )\r
130                 {\r
131                         List<C曲リストノード> songList = GetSongListWithinMe( song );\r
132                         return ( songList == null ) ? null : songList[ songList.Count - 1 ];\r
133                 }\r
134 \r
135                 private List<C曲リストノード> GetSongListWithinMe( C曲リストノード song )\r
136                 {\r
137                         if ( song.r親ノード == null )                                       // root階層のノートだったら\r
138                         {\r
139                                 return CDTXMania.Songs管理.list曲ルート;  // rootのリストを返す\r
140                         }\r
141                         else\r
142                         {\r
143                                 if ( ( song.r親ノード.list子リスト != null ) && ( song.r親ノード.list子リスト.Count > 0 ) )\r
144                                 {\r
145                                         return song.r親ノード.list子リスト;\r
146                                 }\r
147                                 else\r
148                                 {\r
149                                         return null;\r
150                                 }\r
151                         }\r
152                 }\r
153 \r
154 \r
155                 public delegate void DGSortFunc( List<C曲リストノード> songList, E楽器パート eInst, int order, params object[] p);\r
156                 /// <summary>\r
157                 /// 主にCSong管理.cs内にあるソート機能を、delegateで呼び出す。\r
158                 /// </summary>\r
159                 /// <param name="sf">ソート用に呼び出すメソッド</param>\r
160                 /// <param name="eInst">ソート基準とする楽器</param>\r
161                 /// <param name="order">-1=降順, 1=昇順</param>\r
162                 public void t曲リストのソート( DGSortFunc sf, E楽器パート eInst, int order, params object[] p )\r
163                 {\r
164                         List<C曲リストノード> songList = GetSongListWithinMe( this.r現在選択中の曲 );\r
165                         if ( songList == null )\r
166                         {\r
167                                 // 何もしない;\r
168                         }\r
169                         else\r
170                         {\r
171 //                              CDTXMania.Songs管理.t曲リストのソート3_演奏回数の多い順( songList, eInst, order );\r
172                                 sf( songList, eInst, order, p );\r
173 //                              this.r現在選択中の曲 = CDTXMania\r
174                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
175                         }\r
176                 }\r
177 \r
178                 public void tBOXに入る()\r
179                 {\r
180                         if( ( this.r現在選択中の曲.list子リスト != null ) && ( this.r現在選択中の曲.list子リスト.Count > 0 ) )\r
181                         {\r
182                                 this.r現在選択中の曲 = this.r現在選択中の曲.list子リスト[ 0 ];\r
183                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
184                                 this.t選択曲が変更された();                                                                    // #27648 項目数変更を反映させる\r
185                         }\r
186                 }\r
187                 public void tBOXを出る()\r
188                 {\r
189                         if( this.r現在選択中の曲.r親ノード != null )\r
190                         {\r
191                                 this.r現在選択中の曲 = this.r現在選択中の曲.r親ノード;\r
192                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
193                                 this.t選択曲が変更された();                                                                    // #27648 項目数変更を反映させる\r
194                         }\r
195                 }\r
196                 public void t現在選択中の曲を元に曲バーを再構成する()\r
197                 {\r
198                         this.tバーの初期化();\r
199                         for( int i = 0; i < 13; i++ )\r
200                         {\r
201                                 this.t曲名バーの生成( i, this.stバー情報[ i ].strタイトル文字列, this.stバー情報[ i ].col文字色 );\r
202                         }\r
203                 }\r
204                 public void t次に移動()\r
205                 {\r
206                         if( this.r現在選択中の曲 != null )\r
207                         {\r
208                                 this.n目標のスクロールカウンタ += 100;\r
209                         }\r
210                 }\r
211                 public void t前に移動()\r
212                 {\r
213                         if( this.r現在選択中の曲 != null )\r
214                         {\r
215                                 this.n目標のスクロールカウンタ -= 100;\r
216                         }\r
217                 }\r
218                 public void t難易度レベルをひとつ進める()\r
219                 {\r
220                         if( ( this.r現在選択中の曲 == null ) || ( this.r現在選択中の曲.nスコア数 <= 1 ) )\r
221                                 return;         // 曲にスコアが0~1個しかないなら進める意味なし。\r
222                         \r
223 \r
224                         // 難易度レベルを+1し、現在選曲中のスコアを変更する。\r
225 \r
226                         this.n現在のアンカ難易度レベル = this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( this.r現在選択中の曲 );\r
227 \r
228                         for( int i = 0; i < 5; i++ )\r
229                         {\r
230                                 this.n現在のアンカ難易度レベル = ( this.n現在のアンカ難易度レベル + 1 ) % 5;    // 5以上になったら0に戻る。\r
231                                 if( this.r現在選択中の曲.arスコア[ this.n現在のアンカ難易度レベル ] != null )     // 曲が存在してるならここで終了。存在してないなら次のレベルへGo。\r
232                                         break;\r
233                         }\r
234 \r
235 \r
236                         // 曲毎に表示しているスキル値を、新しい難易度レベルに合わせて取得し直す。(表示されている13曲全部。)\r
237 \r
238                         C曲リストノード song = this.r現在選択中の曲;\r
239                         for( int i = 0; i < 5; i++ )\r
240                                 song = this.r前の曲( song );\r
241 \r
242                         for( int i = this.n現在の選択行 - 5; i < ( ( this.n現在の選択行 - 5 ) + 13 ); i++ )\r
243                         {\r
244                                 int index = ( i + 13 ) % 13;\r
245                                 for( int m = 0; m < 3; m++ )\r
246                                 {\r
247                                         this.stバー情報[ index ].nスキル値[ m ] = (int) song.arスコア[ this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( song ) ].譜面情報.最大スキル[ m ];\r
248                                 }\r
249                                 song = this.r次の曲( song );\r
250                         }\r
251 \r
252 \r
253                         // 選曲ステージに変更通知を発出し、関係Activityの対応を行ってもらう。\r
254 \r
255                         CDTXMania.stage選曲.t選択曲変更通知();\r
256                 }\r
257 \r
258 \r
259                 /// <summary>\r
260                 /// 曲リストをリセットする\r
261                 /// </summary>\r
262                 /// <param name="cs"></param>\r
263                 public void Refresh(CSongs管理 cs, bool bRemakeSongTitleBar )         // #26070 2012.2.28 yyagi\r
264                 {\r
265 //                      this.On非活性化();\r
266 \r
267                         if ( cs != null && cs.list曲ルート.Count > 0 )      // 新しい曲リストを検索して、1曲以上あった\r
268                         {\r
269                                 CDTXMania.Songs管理 = cs;\r
270 \r
271                                 if ( this.r現在選択中の曲 != null )                      // r現在選択中の曲==null とは、「最初songlist.dbが無かった or 検索したが1曲もない」\r
272                                 {\r
273                                         this.r現在選択中の曲 = searchCurrentBreadcrumbsPosition( CDTXMania.Songs管理.list曲ルート, this.r現在選択中の曲.strBreadcrumbs );\r
274                                         if ( bRemakeSongTitleBar )                                      // 選曲画面以外に居るときには再構成しない (非活性化しているときに実行すると例外となる)\r
275                                         {\r
276                                                 this.t現在選択中の曲を元に曲バーを再構成する();\r
277                                         }\r
278 #if false                       // list子リストの中まではmatchしてくれないので、検索ロジックは手書きで実装 (searchCurrentBreadcrumbs())\r
279                                         string bc = this.r現在選択中の曲.strBreadcrumbs;\r
280                                         Predicate<C曲リストノード> match = delegate( C曲リストノード c )\r
281                                         {\r
282                                                 return ( c.strBreadcrumbs.Equals( bc ) );\r
283                                         };\r
284                                         int nMatched = CDTXMania.Songs管理.list曲ルート.FindIndex( match );\r
285 \r
286                                         this.r現在選択中の曲 = ( nMatched == -1 ) ? null : CDTXMania.Songs管理.list曲ルート[ nMatched ];\r
287                                         this.t現在選択中の曲を元に曲バーを再構成する();\r
288 #endif\r
289                                         return;\r
290                                 }\r
291                         }\r
292                         this.On非活性化();\r
293                         this.r現在選択中の曲 = null;\r
294                         this.On活性化();\r
295                 }\r
296 \r
297 \r
298                 /// <summary>\r
299                 /// 現在選曲している位置を検索する\r
300                 /// (曲一覧クラスを新しいものに入れ替える際に用いる)\r
301                 /// </summary>\r
302                 /// <param name="ln">検索対象のList</param>\r
303                 /// <param name="bc">検索するパンくずリスト(文字列)</param>\r
304                 /// <returns></returns>\r
305                 private C曲リストノード searchCurrentBreadcrumbsPosition( List<C曲リストノード> ln, string bc )\r
306                 {\r
307                         foreach (C曲リストノード n in ln)\r
308                         {\r
309                                 if ( n.strBreadcrumbs == bc )\r
310                                 {\r
311                                         return n;\r
312                                 }\r
313                                 else if ( n.list子リスト != null && n.list子リスト.Count > 0 )  // 子リストが存在するなら、再帰で探す\r
314                                 {\r
315                                         C曲リストノード r = searchCurrentBreadcrumbsPosition( n.list子リスト, bc );\r
316                                         if ( r != null ) return r;\r
317                                 }\r
318                         }\r
319                         return null;\r
320                 }\r
321 \r
322                 /// <summary>\r
323                 /// BOXのアイテム数と、今何番目を選択しているかをセットする\r
324                 /// </summary>\r
325                 public void t選択曲が変更された()      // #27648\r
326                 {\r
327                         C曲リストノード song = CDTXMania.stage選曲.r現在選択中の曲;\r
328                         if ( song == null )\r
329                                 return;\r
330                         List<C曲リストノード> list = ( song.r親ノード != null ) ? song.r親ノード.list子リスト : CDTXMania.Songs管理.list曲ルート;\r
331                         int index = list.IndexOf( song ) + 1;\r
332                         if ( index <= 0 )\r
333                         {\r
334                                 nCurrentPosition = nNumOfItems = 0;\r
335                         }\r
336                         else\r
337                         {\r
338                                 nCurrentPosition = index;\r
339                                 nNumOfItems = list.Count;\r
340                         }\r
341                 }\r
342 \r
343                 // CActivity 実装\r
344 \r
345                 public override void On活性化()\r
346                 {\r
347                         if( this.b活性化してる )\r
348                                 return;\r
349 \r
350                         this.e楽器パート = E楽器パート.DRUMS;\r
351                         this.b登場アニメ全部完了 = false;\r
352                         this.n目標のスクロールカウンタ = 0;\r
353                         this.n現在のスクロールカウンタ = 0;\r
354                         this.nスクロールタイマ = -1;\r
355 \r
356                         // フォント作成。\r
357                         // 曲リスト文字は2倍(面積4倍)でテクスチャに描画してから縮小表示するので、フォントサイズは2倍とする。\r
358 \r
359                         FontStyle regular = FontStyle.Regular;\r
360                         if( CDTXMania.ConfigIni.b選曲リストフォントを斜体にする ) regular |= FontStyle.Italic;\r
361                         if( CDTXMania.ConfigIni.b選曲リストフォントを太字にする ) regular |= FontStyle.Bold;\r
362                         this.ft曲リスト用フォント = new Font( CDTXMania.ConfigIni.str選曲リストフォント, (float) ( CDTXMania.ConfigIni.n選曲リストフォントのサイズdot * 2 ), regular, GraphicsUnit.Pixel );\r
363                         \r
364 \r
365                         // 現在選択中の曲がない(=はじめての活性化)なら、現在選択中の曲をルートの先頭ノードに設定する。\r
366 \r
367                         if( ( this.r現在選択中の曲 == null ) && ( CDTXMania.Songs管理.list曲ルート.Count > 0 ) )\r
368                                 this.r現在選択中の曲 = CDTXMania.Songs管理.list曲ルート[ 0 ];\r
369 \r
370 \r
371                         // バー情報を初期化する。\r
372 \r
373                         this.tバーの初期化();\r
374 \r
375                         base.On活性化();\r
376                 }\r
377                 public override void On非活性化()\r
378                 {\r
379                         if( this.b活性化してない )\r
380                                 return;\r
381 \r
382                         CDTXMania.t安全にDisposeする( ref this.ft曲リスト用フォント );\r
383 \r
384                         for( int i = 0; i < 13; i++ )\r
385                                 this.ct登場アニメ用[ i ] = null;\r
386 \r
387                         base.On非活性化();\r
388                 }\r
389                 public override void OnManagedリソースの作成()\r
390                 {\r
391                         if( this.b活性化してない )\r
392                                 return;\r
393 \r
394                         this.tx曲名バー.Score = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect bar score.png" ), false );\r
395                         this.tx曲名バー.Box = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect bar box.png" ), false );\r
396                         this.tx曲名バー.Other = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect bar other.png" ), false );\r
397                         this.tx選曲バー.Score = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect bar score selected.png" ), false );\r
398                         this.tx選曲バー.Box = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect bar box selected.png" ), false );\r
399                         this.tx選曲バー.Other = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect bar other selected.png" ), false );\r
400                         this.txスキル数字 = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect skill number on list.png" ), false );\r
401                         for( int i = 0; i < 13; i++ )\r
402                                 this.t曲名バーの生成( i, this.stバー情報[ i ].strタイトル文字列, this.stバー情報[ i ].col文字色 );\r
403 \r
404                         int c = ( CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja" ) ? 0 : 1;\r
405                         #region [ Songs not found画像 ]\r
406                         try\r
407                         {\r
408                                 using( Bitmap image = new Bitmap( 640, 128 ) )\r
409                                 using( Graphics graphics = Graphics.FromImage( image ) )\r
410                                 {\r
411                                         string[] s1 = { "曲データが見つかりません。", "Songs not found." };\r
412                                         string[] s2 = { "曲データをDTXManiaGR.exe以下の", "You need to install songs." };\r
413                                         string[] s3 = { "フォルダにインストールして下さい。", "" };\r
414                                         graphics.DrawString( s1[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float) 2f, (float) 2f );\r
415                                         graphics.DrawString( s1[c], this.ft曲リスト用フォント, Brushes.White, (float) 0f, (float) 0f );\r
416                                         graphics.DrawString( s2[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float) 2f, (float) 44f );\r
417                                         graphics.DrawString( s2[c], this.ft曲リスト用フォント, Brushes.White, (float) 0f, (float) 42f );\r
418                                         graphics.DrawString( s3[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float) 2f, (float) 86f );\r
419                                         graphics.DrawString( s3[c], this.ft曲リスト用フォント, Brushes.White, (float) 0f, (float) 84f );\r
420 \r
421                                         this.txSongNotFound = new CTexture( CDTXMania.app.Device, image, CDTXMania.TextureFormat );\r
422 \r
423                                         this.txSongNotFound.vc拡大縮小倍率 = new Vector3( 0.5f, 0.5f, 1f );       // 半分のサイズで表示する。\r
424                                 }\r
425                         }\r
426                         catch( CTextureCreateFailedException )\r
427                         {\r
428                                 Trace.TraceError( "SoungNotFoundテクスチャの作成に失敗しました。" );\r
429                                 this.txSongNotFound = null;\r
430                         }\r
431                         #endregion\r
432                         #region [ "曲データを検索しています"画像 ]\r
433                         try\r
434                         {\r
435                                 using ( Bitmap image = new Bitmap( 640, 96 ) )\r
436                                 using ( Graphics graphics = Graphics.FromImage( image ) )\r
437                                 {\r
438                                         string[] s1 = { "曲データを検索しています。", "Now enumerating songs." };\r
439                                         string[] s2 = { "そのまましばらくお待ち下さい。", "Please wait..." };\r
440                                         graphics.DrawString( s1[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float) 2f, (float) 2f );\r
441                                         graphics.DrawString( s1[c], this.ft曲リスト用フォント, Brushes.White, (float) 0f, (float) 0f );\r
442                                         graphics.DrawString( s2[c], this.ft曲リスト用フォント, Brushes.DarkGray, (float) 2f, (float) 44f );\r
443                                         graphics.DrawString( s2[c], this.ft曲リスト用フォント, Brushes.White, (float) 0f, (float) 42f );\r
444 \r
445                                         this.txEnumeratingSongs = new CTexture( CDTXMania.app.Device, image, CDTXMania.TextureFormat );\r
446 \r
447                                         this.txEnumeratingSongs.vc拡大縮小倍率 = new Vector3( 0.5f, 0.5f, 1f );   // 半分のサイズで表示する。\r
448                                 }\r
449                         }\r
450                         catch ( CTextureCreateFailedException )\r
451                         {\r
452                                 Trace.TraceError( "txEnumeratingSongsテクスチャの作成に失敗しました。" );\r
453                                 this.txEnumeratingSongs = null;\r
454                         }\r
455                         #endregion\r
456                         #region [ スクロールバー #27648 ]\r
457                         this.txアイテム数数字 = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect skill number on gauge etc.png" ), false );\r
458                         this.txScrollBar = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect scrollbar.png" ), false );\r
459                         this.txScrollPosition = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect scrollbar.png" ), false );\r
460                         #endregion\r
461 \r
462                         base.OnManagedリソースの作成();\r
463                 }\r
464                 public override void OnManagedリソースの解放()\r
465                 {\r
466                         if( this.b活性化してない )\r
467                                 return;\r
468                         CDTXMania.t安全にDisposeする( ref this.txアイテム数数字 );\r
469                         CDTXMania.t安全にDisposeする( ref this.txScrollBar );\r
470                         CDTXMania.t安全にDisposeする( ref this.txScrollPosition );\r
471 \r
472                         for( int i = 0; i < 13; i++ )\r
473                                 CDTXMania.t安全にDisposeする( ref this.stバー情報[ i ].txタイトル名 );\r
474 \r
475                         CDTXMania.t安全にDisposeする( ref this.txスキル数字 );\r
476                         CDTXMania.t安全にDisposeする( ref this.txEnumeratingSongs );\r
477                         CDTXMania.t安全にDisposeする( ref this.txSongNotFound );\r
478                         CDTXMania.t安全にDisposeする( ref this.tx曲名バー.Score );\r
479                         CDTXMania.t安全にDisposeする( ref this.tx曲名バー.Box );\r
480                         CDTXMania.t安全にDisposeする( ref this.tx曲名バー.Other );\r
481                         CDTXMania.t安全にDisposeする( ref this.tx選曲バー.Score );\r
482                         CDTXMania.t安全にDisposeする( ref this.tx選曲バー.Box );\r
483                         CDTXMania.t安全にDisposeする( ref this.tx選曲バー.Other );\r
484 \r
485                         base.OnManagedリソースの解放();\r
486                 }\r
487                 public override int On進行描画()\r
488                 {\r
489                         if( this.b活性化してない )\r
490                                 return 0;\r
491 \r
492                         #region [ 初めての進行描画 ]\r
493                         //-----------------\r
494                         if( this.b初めての進行描画 )\r
495                         {\r
496                                 for( int i = 0; i < 13; i++ )\r
497                                         this.ct登場アニメ用[ i ] = new CCounter( -i * 10, 100, 3, CDTXMania.Timer );\r
498 \r
499                                 this.nスクロールタイマ = CDTXMania.Timer.n現在時刻;\r
500                                 CDTXMania.stage選曲.t選択曲変更通知();\r
501                                 \r
502                                 base.b初めての進行描画 = false;\r
503                         }\r
504                         //-----------------\r
505                         #endregion\r
506 \r
507                         \r
508                         // まだ選択中の曲が決まってなければ、曲ツリールートの最初の曲にセットする。\r
509 \r
510                         if( ( this.r現在選択中の曲 == null ) && ( CDTXMania.Songs管理.list曲ルート.Count > 0 ) )\r
511                                 this.r現在選択中の曲 = CDTXMania.Songs管理.list曲ルート[ 0 ];\r
512 \r
513 \r
514                         // 本ステージは、(1)登場アニメフェーズ → (2)通常フェーズ と二段階にわけて進む。\r
515                         // 2つしかフェーズがないので CStage.eフェーズID を使ってないところがまた本末転倒。\r
516 \r
517                         \r
518                         // 進行。\r
519 \r
520                         if( !this.b登場アニメ全部完了 )\r
521                         {\r
522                                 #region [ (1) 登場アニメフェーズの進行。]\r
523                                 //-----------------\r
524                                 for( int i = 0; i < 13; i++ )   // パネルは全13枚。\r
525                                 {\r
526                                         this.ct登場アニメ用[ i ].t進行();\r
527 \r
528                                         if( this.ct登場アニメ用[ i ].b終了値に達した )\r
529                                                 this.ct登場アニメ用[ i ].t停止();\r
530                                 }\r
531 \r
532                                 // 全部の進行が終わったら、this.b登場アニメ全部完了 を true にする。\r
533 \r
534                                 this.b登場アニメ全部完了 = true;\r
535                                 for( int i = 0; i < 13; i++ )   // パネルは全13枚。\r
536                                 {\r
537                                         if( this.ct登場アニメ用[ i ].b進行中 )\r
538                                         {\r
539                                                 this.b登場アニメ全部完了 = false;      // まだ進行中のアニメがあるなら false のまま。\r
540                                                 break;\r
541                                         }\r
542                                 }\r
543                                 //-----------------\r
544                                 #endregion\r
545                         }\r
546                         else\r
547                         {\r
548                                 #region [ (2) 通常フェーズの進行。]\r
549                                 //-----------------\r
550                                 long n現在時刻 = CDTXMania.Timer.n現在時刻;\r
551                                 \r
552                                 if( n現在時刻 < this.nスクロールタイマ )    // 念のため\r
553                                         this.nスクロールタイマ = n現在時刻;\r
554 \r
555                                 const int nアニメ間隔 = 2;\r
556                                 while( ( n現在時刻 - this.nスクロールタイマ ) >= nアニメ間隔 )\r
557                                 {\r
558                                         int n加速度 = 1;\r
559                                         int n残距離 = Math.Abs( (int) ( this.n目標のスクロールカウンタ - this.n現在のスクロールカウンタ ) );\r
560 \r
561                                         #region [ 残距離が遠いほどスクロールを速くする(=n加速度を多くする)。]\r
562                                         //-----------------\r
563                                         if( n残距離 <= 100 )\r
564                                         {\r
565                                                 n加速度 = 2;\r
566                                         }\r
567                                         else if( n残距離 <= 300 )\r
568                                         {\r
569                                                 n加速度 = 3;\r
570                                         }\r
571                                         else if( n残距離 <= 500 )\r
572                                         {\r
573                                                 n加速度 = 4;\r
574                                         }\r
575                                         else\r
576                                         {\r
577                                                 n加速度 = 8;\r
578                                         }\r
579                                         //-----------------\r
580                                         #endregion\r
581 \r
582                                         #region [ 加速度を加算し、現在のスクロールカウンタを目標のスクロールカウンタまで近づける。 ]\r
583                                         //-----------------\r
584                                         if( this.n現在のスクロールカウンタ < this.n目標のスクロールカウンタ )           // (A) 正の方向に未達の場合:\r
585                                         {\r
586                                                 this.n現在のスクロールカウンタ += n加速度;                                                               // カウンタを正方向に移動する。\r
587 \r
588                                                 if( this.n現在のスクロールカウンタ > this.n目標のスクロールカウンタ )\r
589                                                         this.n現在のスクロールカウンタ = this.n目標のスクロールカウンタ;        // 到着!スクロール停止!\r
590                                         }\r
591 \r
592                                         else if( this.n現在のスクロールカウンタ > this.n目標のスクロールカウンタ )      // (B) 負の方向に未達の場合:\r
593                                         {\r
594                                                 this.n現在のスクロールカウンタ -= n加速度;                                                               // カウンタを負方向に移動する。\r
595 \r
596                                                 if( this.n現在のスクロールカウンタ < this.n目標のスクロールカウンタ )   // 到着!スクロール停止!\r
597                                                         this.n現在のスクロールカウンタ = this.n目標のスクロールカウンタ;\r
598                                         }\r
599                                         //-----------------\r
600                                         #endregion\r
601 \r
602                                         if( this.n現在のスクロールカウンタ >= 100 )         // 1行=100カウント。\r
603                                         {\r
604                                                 #region [ パネルを1行上にシフトする。]\r
605                                                 //-----------------\r
606 \r
607                                                 // 選択曲と選択行を1つ下の行に移動。\r
608 \r
609                                                 this.r現在選択中の曲 = this.r次の曲( this.r現在選択中の曲 );\r
610                                                 this.n現在の選択行 = ( this.n現在の選択行 + 1 ) % 13;\r
611 \r
612 \r
613                                                 // 選択曲から7つ下のパネル(=新しく最下部に表示されるパネル。消えてしまう一番上のパネルを再利用する)に、新しい曲の情報を記載する。\r
614 \r
615                                                 C曲リストノード song = this.r現在選択中の曲;\r
616                                                 for( int i = 0; i < 7; i++ )\r
617                                                         song = this.r次の曲( song );\r
618 \r
619                                                 int index = ( this.n現在の選択行 + 7 ) % 13;      // 新しく最下部に表示されるパネルのインデックス(0~12)。\r
620                                                 this.stバー情報[ index ].strタイトル文字列 = song.strタイトル;\r
621                                                 this.stバー情報[ index ].col文字色 = song.col文字色;\r
622                                                 this.t曲名バーの生成( index, this.stバー情報[ index ].strタイトル文字列, this.stバー情報[ index ].col文字色 );\r
623 \r
624 \r
625                                                 // stバー情報[] の内容を1行ずつずらす。\r
626                                                 \r
627                                                 C曲リストノード song2 = this.r現在選択中の曲;\r
628                                                 for( int i = 0; i < 5; i++ )\r
629                                                         song2 = this.r前の曲( song2 );\r
630 \r
631                                                 for( int i = 0; i < 13; i++ )\r
632                                                 {\r
633                                                         int n = ( ( ( this.n現在の選択行 - 5 ) + i ) + 13 ) % 13;\r
634                                                         this.stバー情報[ n ].eバー種別 = this.e曲のバー種別を返す( song2 );\r
635                                                         song2 = this.r次の曲( song2 );\r
636                                                 }\r
637 \r
638                                                 \r
639                                                 // 新しく最下部に表示されるパネル用のスキル値を取得。\r
640 \r
641                                                 for( int i = 0; i < 3; i++ )\r
642                                                         this.stバー情報[ index ].nスキル値[ i ] = (int) song.arスコア[ this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( song ) ].譜面情報.最大スキル[ i ];\r
643 \r
644 \r
645                                                 // 1行(100カウント)移動完了。\r
646 \r
647                                                 this.n現在のスクロールカウンタ -= 100;\r
648                                                 this.n目標のスクロールカウンタ -= 100;\r
649 \r
650                                                 this.t選択曲が変更された();                                            // スクロールバー用に今何番目を選択しているかを更新\r
651 \r
652                                                 if( this.n目標のスクロールカウンタ == 0 )\r
653                                                         CDTXMania.stage選曲.t選択曲変更通知();         // スクロール完了=選択曲変更!\r
654 \r
655                                                 //-----------------\r
656                                                 #endregion\r
657                                         }\r
658                                         else if( this.n現在のスクロールカウンタ <= -100 )\r
659                                         {\r
660                                                 #region [ パネルを1行下にシフトする。]\r
661                                                 //-----------------\r
662 \r
663                                                 // 選択曲と選択行を1つ上の行に移動。\r
664 \r
665                                                 this.r現在選択中の曲 = this.r前の曲( this.r現在選択中の曲 );\r
666                                                 this.n現在の選択行 = ( ( this.n現在の選択行 - 1 ) + 13 ) % 13;\r
667 \r
668 \r
669                                                 // 選択曲から5つ上のパネル(=新しく最上部に表示されるパネル。消えてしまう一番下のパネルを再利用する)に、新しい曲の情報を記載する。\r
670 \r
671                                                 C曲リストノード song = this.r現在選択中の曲;\r
672                                                 for( int i = 0; i < 5; i++ )\r
673                                                         song = this.r前の曲( song );\r
674 \r
675                                                 int index = ( ( this.n現在の選択行 - 5 ) + 13 ) % 13;     // 新しく最上部に表示されるパネルのインデックス(0~12)。\r
676                                                 this.stバー情報[ index ].strタイトル文字列 = song.strタイトル;\r
677                                                 this.stバー情報[ index ].col文字色 = song.col文字色;\r
678                                                 this.t曲名バーの生成( index, this.stバー情報[ index ].strタイトル文字列, this.stバー情報[ index ].col文字色 );\r
679 \r
680 \r
681                                                 // stバー情報[] の内容を1行ずつずらす。\r
682                                                 \r
683                                                 C曲リストノード song2 = this.r現在選択中の曲;\r
684                                                 for( int i = 0; i < 5; i++ )\r
685                                                         song2 = this.r前の曲( song2 );\r
686 \r
687                                                 for( int i = 0; i < 13; i++ )\r
688                                                 {\r
689                                                         int n = ( ( ( this.n現在の選択行 - 5 ) + i ) + 13 ) % 13;\r
690                                                         this.stバー情報[ n ].eバー種別 = this.e曲のバー種別を返す( song2 );\r
691                                                         song2 = this.r次の曲( song2 );\r
692                                                 }\r
693 \r
694                 \r
695                                                 // 新しく最上部に表示されるパネル用のスキル値を取得。\r
696                                                 \r
697                                                 for( int i = 0; i < 3; i++ )\r
698                                                         this.stバー情報[ index ].nスキル値[ i ] = (int) song.arスコア[ this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( song ) ].譜面情報.最大スキル[ i ];\r
699 \r
700 \r
701                                                 // 1行(100カウント)移動完了。\r
702 \r
703                                                 this.n現在のスクロールカウンタ += 100;\r
704                                                 this.n目標のスクロールカウンタ += 100;\r
705 \r
706                                                 this.t選択曲が変更された();                                            // スクロールバー用に今何番目を選択しているかを更新\r
707 \r
708                                                 if( this.n目標のスクロールカウンタ == 0 )\r
709                                                         CDTXMania.stage選曲.t選択曲変更通知();         // スクロール完了=選択曲変更!\r
710                                                 //-----------------\r
711                                                 #endregion\r
712                                         }\r
713 \r
714                                         this.nスクロールタイマ += nアニメ間隔;\r
715                                 }\r
716                                 //-----------------\r
717                                 #endregion\r
718                         }\r
719 \r
720 \r
721                         // 描画。\r
722 \r
723                         if( this.r現在選択中の曲 == null )\r
724                         {\r
725                                 #region [ 曲が1つもないなら「Songs not found.」を表示してここで帰れ。]\r
726                                 //-----------------\r
727                                 if ( bIsEnumeratingSongs )\r
728                                 {\r
729                                         if ( this.txEnumeratingSongs != null )\r
730                                         {\r
731                                                 this.txEnumeratingSongs.t2D描画( CDTXMania.app.Device, 320, 160 );\r
732                                         }\r
733                                 }\r
734                                 else\r
735                                 {\r
736                                         if ( this.txSongNotFound != null )\r
737                                                 this.txSongNotFound.t2D描画( CDTXMania.app.Device, 320, 160 );\r
738                                 }\r
739                                 //-----------------\r
740                                 #endregion\r
741 \r
742                                 return 0;\r
743                         }\r
744 \r
745                         if( !this.b登場アニメ全部完了 )\r
746                         {\r
747                                 #region [ (1) 登場アニメフェーズの描画。]\r
748                                 //-----------------\r
749                                 for( int i = 0; i < 13; i++ )   // パネルは全13枚。\r
750                                 {\r
751                                         if( this.ct登場アニメ用[ i ].n現在の値 >= 0 )\r
752                                         {\r
753                                                 double db割合0to1 = ( (double) this.ct登場アニメ用[ i ].n現在の値 ) / 100.0;\r
754                                                 double db回転率 = Math.Sin( Math.PI * 3 / 5 * db割合0to1 );\r
755                                                 int nパネル番号 = ( ( ( this.n現在の選択行 - 5 ) + i ) + 13 ) % 13;\r
756                                                 \r
757                                                 if( i == 5 )\r
758                                                 {\r
759                                                         // (A) 選択曲パネルを描画。\r
760 \r
761                                                         #region [ バーテクスチャを描画。]\r
762                                                         //-----------------\r
763                                                         int width = (int) ( 425.0 / Math.Sin( Math.PI * 3 / 5 ) );\r
764                                                         int x = 640 - ( (int) ( width * db回転率 ) );\r
765                                                         int y = 181;\r
766                                                         this.tバーの描画( x, y, this.stバー情報[ nパネル番号 ].eバー種別, true );\r
767                                                         //-----------------\r
768                                                         #endregion\r
769                                                         #region [ タイトル名テクスチャを描画。]\r
770                                                         //-----------------\r
771                                                         if( this.stバー情報[ nパネル番号 ].txタイトル名 != null )\r
772                                                                 this.stバー情報[ nパネル番号 ].txタイトル名.t2D描画( CDTXMania.app.Device, ( x + 44 ) + 16, ( y + 4 ) + 16 );\r
773                                                         //-----------------\r
774                                                         #endregion\r
775                                                         #region [ スキル値を描画。]\r
776                                                         //-----------------\r
777                                                         if( ( this.stバー情報[ nパネル番号 ].eバー種別 == Eバー種別.Score ) && ( this.e楽器パート != E楽器パート.UNKNOWN ) )\r
778                                                                 this.tスキル値の描画( x + 28, y + 30, this.stバー情報[ nパネル番号 ].nスキル値[ (int) this.e楽器パート ] );\r
779                                                         //-----------------\r
780                                                         #endregion\r
781                                                 }\r
782                                                 else\r
783                                                 {\r
784                                                         // (B) その他のパネルの描画。\r
785 \r
786                                                         #region [ バーテクスチャの描画。]\r
787                                                         //-----------------\r
788                                                         int width = (int) ( ( (double) ( ( 640 - this.ptバーの基本座標[ i ].X ) + 1 ) ) / Math.Sin( Math.PI * 3 / 5 ) );\r
789                                                         int x = 640 - ( (int) ( width * db回転率 ) );\r
790                                                         int y = this.ptバーの基本座標[ i ].Y;\r
791                                                         this.tバーの描画( x, y, this.stバー情報[ nパネル番号 ].eバー種別, false );\r
792                                                         //-----------------\r
793                                                         #endregion\r
794                                                         #region [ タイトル名テクスチャを描画。]\r
795                                                         //-----------------\r
796                                                         if( this.stバー情報[ nパネル番号 ].txタイトル名 != null )\r
797                                                                 this.stバー情報[ nパネル番号 ].txタイトル名.t2D描画( CDTXMania.app.Device, x + 44, y + 4 );\r
798                                                         //-----------------\r
799                                                         #endregion\r
800                                                         #region [ スキル値を描画。]\r
801                                                         //-----------------\r
802                                                         if( ( this.stバー情報[ nパネル番号 ].eバー種別 == Eバー種別.Score ) && ( this.e楽器パート != E楽器パート.UNKNOWN ) )\r
803                                                                 this.tスキル値の描画( x + 14, y + 14, this.stバー情報[ nパネル番号 ].nスキル値[ (int) this.e楽器パート ] );\r
804                                                         //-----------------\r
805                                                         #endregion\r
806                                                 }\r
807                                         }\r
808                                 }\r
809                                 //-----------------\r
810                                 #endregion\r
811                         }\r
812                         else\r
813                         {\r
814                                 #region [ (2) 通常フェーズの描画。]\r
815                                 //-----------------\r
816                                 for( int i = 0; i < 13; i++ )   // パネルは全13枚。\r
817                                 {\r
818                                         if( ( i == 0 && this.n現在のスクロールカウンタ > 0 ) ||             // 最上行は、上に移動中なら表示しない。\r
819                                                 ( i == 12 && this.n現在のスクロールカウンタ < 0 ) )         // 最下行は、下に移動中なら表示しない。\r
820                                                 continue;\r
821 \r
822                                         int nパネル番号 = ( ( ( this.n現在の選択行 - 5 ) + i ) + 13 ) % 13;\r
823                                         int n見た目の行番号 = i;\r
824                                         int n次のパネル番号 = ( this.n現在のスクロールカウンタ <= 0 ) ? ( ( i + 1 ) % 13 ) : ( ( ( i - 1 ) + 13 ) % 13 );\r
825                                         int x = this.ptバーの基本座標[ n見た目の行番号 ].X + ( (int) ( ( this.ptバーの基本座標[ n次のパネル番号 ].X - this.ptバーの基本座標[ n見た目の行番号 ].X ) * ( ( (double) Math.Abs( this.n現在のスクロールカウンタ ) ) / 100.0 ) ) );\r
826                                         int y = this.ptバーの基本座標[ n見た目の行番号 ].Y + ( (int) ( ( this.ptバーの基本座標[ n次のパネル番号 ].Y - this.ptバーの基本座標[ n見た目の行番号 ].Y ) * ( ( (double) Math.Abs( this.n現在のスクロールカウンタ ) ) / 100.0 ) ) );\r
827                 \r
828                                         if( ( i == 5 ) && ( this.n現在のスクロールカウンタ == 0 ) )\r
829                                         {\r
830                                                 // (A) スクロールが停止しているときの選択曲バーの描画。\r
831 \r
832                                                 #region [ バーテクスチャを描画。]\r
833                                                 //-----------------\r
834                                                 this.tバーの描画( 216, 181, this.stバー情報[ nパネル番号 ].eバー種別, true );\r
835                                                 //-----------------\r
836                                                 #endregion\r
837                                                 #region [ タイトル名テクスチャを描画。]\r
838                                                 //-----------------\r
839                                                 if( this.stバー情報[ nパネル番号 ].txタイトル名 != null )\r
840                                                         this.stバー情報[ nパネル番号 ].txタイトル名.t2D描画( CDTXMania.app.Device, 0x114, 0xc9 );\r
841                                                 //-----------------\r
842                                                 #endregion\r
843                                                 #region [ スキル値を描画。]\r
844                                                 //-----------------\r
845                                                 if( ( this.stバー情報[ nパネル番号 ].eバー種別 == Eバー種別.Score ) && ( this.e楽器パート != E楽器パート.UNKNOWN ) )\r
846                                                         this.tスキル値の描画( 0xf4, 0xd3, this.stバー情報[ nパネル番号 ].nスキル値[ (int) this.e楽器パート ] );\r
847                                                 //-----------------\r
848                                                 #endregion\r
849                                         }\r
850                                         else\r
851                                         {\r
852                                                 // (B) スクロール中の選択曲バー、またはその他のバーの描画。\r
853 \r
854                                                 #region [ バーテクスチャを描画。]\r
855                                                 //-----------------\r
856                                                 this.tバーの描画( x, y, this.stバー情報[ nパネル番号 ].eバー種別, false );\r
857                                                 //-----------------\r
858                                                 #endregion\r
859                                                 #region [ タイトル名テクスチャを描画。]\r
860                                                 //-----------------\r
861                                                 if( this.stバー情報[ nパネル番号 ].txタイトル名 != null )\r
862                                                         this.stバー情報[ nパネル番号 ].txタイトル名.t2D描画( CDTXMania.app.Device, x + 44, y + 4 );\r
863                                                 //-----------------\r
864                                                 #endregion\r
865                                                 #region [ スキル値を描画。]\r
866                                                 //-----------------\r
867                                                 if( ( this.stバー情報[ nパネル番号 ].eバー種別 == Eバー種別.Score ) && ( this.e楽器パート != E楽器パート.UNKNOWN ) )\r
868                                                         this.tスキル値の描画( x + 14, y + 14, this.stバー情報[ nパネル番号 ].nスキル値[ (int) this.e楽器パート ] );\r
869                                                 //-----------------\r
870                                                 #endregion\r
871                                         }\r
872                                 }\r
873                                 //-----------------\r
874                                 #endregion\r
875                         }\r
876                         #region [ スクロールバーの描画 #27648 ]\r
877                         for ( int sy = 0; sy < 336; sy += 128 )\r
878                         {\r
879                                 int ry = (sy / 128);\r
880                                 int h = ( ( ry + 1 ) * 128 > 336 ) ? 336 - ry * 128 : 128;\r
881                                 this.txScrollBar.t2D描画( CDTXMania.app.Device, 640 - 12, 58 + sy, new Rectangle( ry * 12 , 0, 12, h ) );     // 本当のy座標は88なんだが、なぜか約30のバイアスが掛かる・・・\r
882                         }\r
883                         #endregion\r
884                         #region [ スクロール地点の描画 #27648 ]\r
885                         int py;\r
886                         double d = 0;\r
887                         if ( nNumOfItems > 1 )\r
888                         {\r
889                                 d = ( 336 - 6 - 8 ) / (double) ( nNumOfItems - 1 );\r
890                                 py = (int) ( d * ( nCurrentPosition - 1 ) );\r
891                         }\r
892                         else\r
893                         {\r
894                                 d = 0;\r
895                                 py = 0;\r
896                         }\r
897                         int delta = (int) ( d * this.n現在のスクロールカウンタ / 100 );\r
898                         if ( py + delta <= 336 - 6 - 8 )\r
899                         {\r
900                                 this.txScrollPosition.t2D描画( CDTXMania.app.Device, 640 - 12 + 3, 58 + 3 + py + delta, new Rectangle( 30, 120, 6, 8 ) );\r
901                         }\r
902                         #endregion\r
903                         #region [ アイテム数の描画 #27648 ]\r
904                         tアイテム数の描画();\r
905                         #endregion\r
906 \r
907                         return 0;\r
908                 }\r
909                 \r
910 \r
911                 // その他\r
912 \r
913                 #region [ private ]\r
914                 //-----------------\r
915                 private enum Eバー種別 { Score, Box, Other }\r
916 \r
917                 private struct STバー\r
918                 {\r
919                         public CTexture Score;\r
920                         public CTexture Box;\r
921                         public CTexture Other;\r
922                         public CTexture this[ int index ]\r
923                         {\r
924                                 get\r
925                                 {\r
926                                         switch( index )\r
927                                         {\r
928                                                 case 0:\r
929                                                         return this.Score;\r
930 \r
931                                                 case 1:\r
932                                                         return this.Box;\r
933 \r
934                                                 case 2:\r
935                                                         return this.Other;\r
936                                         }\r
937                                         throw new IndexOutOfRangeException();\r
938                                 }\r
939                                 set\r
940                                 {\r
941                                         switch( index )\r
942                                         {\r
943                                                 case 0:\r
944                                                         this.Score = value;\r
945                                                         return;\r
946 \r
947                                                 case 1:\r
948                                                         this.Box = value;\r
949                                                         return;\r
950 \r
951                                                 case 2:\r
952                                                         this.Other = value;\r
953                                                         return;\r
954                                         }\r
955                                         throw new IndexOutOfRangeException();\r
956                                 }\r
957                         }\r
958                 }\r
959 \r
960                 private struct STバー情報\r
961                 {\r
962                         public CActSelect曲リスト.Eバー種別 eバー種別;\r
963                         public string strタイトル文字列;\r
964                         public CTexture txタイトル名;\r
965                         public STDGBVALUE<int> nスキル値;\r
966                         public Color col文字色;\r
967                 }\r
968 \r
969                 private struct ST選曲バー\r
970                 {\r
971                         public CTexture Score;\r
972                         public CTexture Box;\r
973                         public CTexture Other;\r
974                         public CTexture this[ int index ]\r
975                         {\r
976                                 get\r
977                                 {\r
978                                         switch( index )\r
979                                         {\r
980                                                 case 0:\r
981                                                         return this.Score;\r
982 \r
983                                                 case 1:\r
984                                                         return this.Box;\r
985 \r
986                                                 case 2:\r
987                                                         return this.Other;\r
988                                         }\r
989                                         throw new IndexOutOfRangeException();\r
990                                 }\r
991                                 set\r
992                                 {\r
993                                         switch( index )\r
994                                         {\r
995                                                 case 0:\r
996                                                         this.Score = value;\r
997                                                         return;\r
998 \r
999                                                 case 1:\r
1000                                                         this.Box = value;\r
1001                                                         return;\r
1002 \r
1003                                                 case 2:\r
1004                                                         this.Other = value;\r
1005                                                         return;\r
1006                                         }\r
1007                                         throw new IndexOutOfRangeException();\r
1008                                 }\r
1009                         }\r
1010                 }\r
1011 \r
1012                 private bool b登場アニメ全部完了;\r
1013                 private Color color文字影 = Color.FromArgb( 0x40, 10, 10, 10 );\r
1014                 private CCounter[] ct登場アニメ用 = new CCounter[ 13 ];\r
1015                 private E楽器パート e楽器パート;\r
1016                 private Font ft曲リスト用フォント;\r
1017                 private long nスクロールタイマ;\r
1018                 private int n現在のスクロールカウンタ;\r
1019                 private int n現在の選択行;\r
1020                 private int n目標のスクロールカウンタ;\r
1021                 private readonly Point[] ptバーの基本座標 = new Point[] { new Point( 0x162, 20 ), new Point( 0x139, 0x36 ), new Point( 0x121, 0x58 ), new Point( 0x111, 0x7a ), new Point( 0x108, 0x9c ), new Point( 0xe8, 0xc5 ), new Point( 0x112, 0x102 ), new Point( 0x121, 0x124 ), new Point( 0x138, 0x146 ), new Point( 0x157, 360 ), new Point( 0x18a, 0x18a ), new Point( 0x1f2, 0x1ac ), new Point( 640, 0x1ce ) };\r
1022                 private STバー情報[] stバー情報 = new STバー情報[ 13 ];\r
1023                 private CTexture txSongNotFound, txEnumeratingSongs;\r
1024                 private CTexture txスキル数字;\r
1025                 private STバー tx曲名バー;\r
1026                 private ST選曲バー tx選曲バー;\r
1027 \r
1028                 private int nCurrentPosition = 0;\r
1029                 private int nNumOfItems = 0;\r
1030                 private CTexture txScrollPosition;\r
1031                 private CTexture txScrollBar;\r
1032                 private CTexture txアイテム数数字;\r
1033 \r
1034                 private Eバー種別 e曲のバー種別を返す( C曲リストノード song )\r
1035                 {\r
1036                         if( song != null )\r
1037                         {\r
1038                                 switch( song.eノード種別 )\r
1039                                 {\r
1040                                         case C曲リストノード.Eノード種別.SCORE:\r
1041                                         case C曲リストノード.Eノード種別.SCORE_MIDI:\r
1042                                                 return Eバー種別.Score;\r
1043 \r
1044                                         case C曲リストノード.Eノード種別.BOX:\r
1045                                         case C曲リストノード.Eノード種別.BACKBOX:\r
1046                                                 return Eバー種別.Box;\r
1047                                 }\r
1048                         }\r
1049                         return Eバー種別.Other;\r
1050                 }\r
1051                 private C曲リストノード r次の曲( C曲リストノード song )\r
1052                 {\r
1053                         if( song == null )\r
1054                                 return null;\r
1055 \r
1056                         List<C曲リストノード> list = ( song.r親ノード != null ) ? song.r親ノード.list子リスト : CDTXMania.Songs管理.list曲ルート;\r
1057         \r
1058                         int index = list.IndexOf( song );\r
1059 \r
1060                         if( index < 0 )\r
1061                                 return null;\r
1062 \r
1063                         if( index == ( list.Count - 1 ) )\r
1064                                 return list[ 0 ];\r
1065 \r
1066                         return list[ index + 1 ];\r
1067                 }\r
1068                 private C曲リストノード r前の曲( C曲リストノード song )\r
1069                 {\r
1070                         if( song == null )\r
1071                                 return null;\r
1072 \r
1073                         List<C曲リストノード> list = ( song.r親ノード != null ) ? song.r親ノード.list子リスト : CDTXMania.Songs管理.list曲ルート;\r
1074 \r
1075                         int index = list.IndexOf( song );\r
1076         \r
1077                         if( index < 0 )\r
1078                                 return null;\r
1079 \r
1080                         if( index == 0 )\r
1081                                 return list[ list.Count - 1 ];\r
1082 \r
1083                         return list[ index - 1 ];\r
1084                 }\r
1085                 private void tスキル値の描画( int x, int y, int nスキル値 )\r
1086                 {\r
1087                         if( nスキル値 <= 0 || nスキル値 > 100 )         // スキル値 0 = 未プレイ なので表示しない。\r
1088                                 return;\r
1089 \r
1090                         int color = ( nスキル値 == 100 ) ? 3 : ( nスキル値 / 25 );\r
1091 \r
1092                         int n百の位 = nスキル値 / 100;\r
1093                         int n十の位 = ( nスキル値 % 100 ) / 10;\r
1094                         int n一の位 = ( nスキル値 % 100 ) % 10;\r
1095 \r
1096 \r
1097                         // 百の位の描画。\r
1098 \r
1099                         if( n百の位 > 0 )\r
1100                                 this.tスキル値の描画・1桁描画( x, y, n百の位, color );\r
1101 \r
1102 \r
1103                         // 十の位の描画。\r
1104 \r
1105                         if( n百の位 != 0 || n十の位 != 0 )\r
1106                                 this.tスキル値の描画・1桁描画( x + 7, y, n十の位, color );\r
1107 \r
1108 \r
1109                         // 一の位の描画。\r
1110 \r
1111                         this.tスキル値の描画・1桁描画( x + 14, y, n一の位, color );\r
1112                 }\r
1113                 private void tスキル値の描画・1桁描画( int x, int y, int n数値, int color )\r
1114                 {\r
1115                         int dx = ( n数値 % 5 ) * 9;\r
1116                         int dy = ( n数値 / 5 ) * 12;\r
1117                         \r
1118                         switch( color )\r
1119                         {\r
1120                                 case 0:\r
1121                                         if( this.txスキル数字 != null )\r
1122                                                 this.txスキル数字.t2D描画( CDTXMania.app.Device, x, y, new Rectangle( 45 + dx, 24 + dy, 9, 12 ) );\r
1123                                         break;\r
1124 \r
1125                                 case 1:\r
1126                                         if( this.txスキル数字 != null )\r
1127                                                 this.txスキル数字.t2D描画( CDTXMania.app.Device, x, y, new Rectangle( 45 + dx, dy, 9, 12 ) );\r
1128                                         break;\r
1129 \r
1130                                 case 2:\r
1131                                         if( this.txスキル数字 != null )\r
1132                                                 this.txスキル数字.t2D描画( CDTXMania.app.Device, x, y, new Rectangle( dx, 24 + dy, 9, 12 ) );\r
1133                                         break;\r
1134 \r
1135                                 case 3:\r
1136                                         if( this.txスキル数字 != null )\r
1137                                                 this.txスキル数字.t2D描画( CDTXMania.app.Device, x, y, new Rectangle( dx, dy, 9, 12 ) );\r
1138                                         break;\r
1139                         }\r
1140                 }\r
1141                 private void tバーの初期化()\r
1142                 {\r
1143                         C曲リストノード song = this.r現在選択中の曲;\r
1144                         \r
1145                         if( song == null )\r
1146                                 return;\r
1147 \r
1148                         for( int i = 0; i < 5; i++ )\r
1149                                 song = this.r前の曲( song );\r
1150 \r
1151                         for( int i = 0; i < 13; i++ )\r
1152                         {\r
1153                                 this.stバー情報[ i ].strタイトル文字列 = song.strタイトル;\r
1154                                 this.stバー情報[ i ].col文字色 = song.col文字色;\r
1155                                 this.stバー情報[ i ].eバー種別 = this.e曲のバー種別を返す( song );\r
1156                                 \r
1157                                 for( int j = 0; j < 3; j++ )\r
1158                                         this.stバー情報[ i ].nスキル値[ j ] = (int) song.arスコア[ this.n現在のアンカ難易度レベルに最も近い難易度レベルを返す( song ) ].譜面情報.最大スキル[ j ];\r
1159 \r
1160                                 song = this.r次の曲( song );\r
1161                         }\r
1162 \r
1163                         this.n現在の選択行 = 5;\r
1164                 }\r
1165                 private void tバーの描画( int x, int y, Eバー種別 type, bool b選択曲 )\r
1166                 {\r
1167                         if( x >= SampleFramework.GameWindowSize.Width || y >= SampleFramework.GameWindowSize.Height )\r
1168                                 return;\r
1169 \r
1170                         if( b選択曲 )\r
1171                         {\r
1172                                 #region [ (A) 選択曲の場合 ]\r
1173                                 //-----------------\r
1174                                 if( this.tx選曲バー[ (int) type ] != null )\r
1175                                         this.tx選曲バー[ (int) type ].t2D描画( CDTXMania.app.Device, x, y, new Rectangle( 0, 0, 128, 64 ) );      // ヘサキ\r
1176                                 x += 128;\r
1177 \r
1178                                 var rc = new Rectangle( 64, 0, 64, 64 );\r
1179                                 while( x < 640 )\r
1180                                 {\r
1181                                         if( this.tx選曲バー[ (int) type ] != null )\r
1182                                                 this.tx選曲バー[ (int) type ].t2D描画( CDTXMania.app.Device, x, y, rc );  // 胴体;64pxずつ横につなげていく。\r
1183                                         x += 64;\r
1184                                 }\r
1185                                 //-----------------\r
1186                                 #endregion\r
1187                         }\r
1188                         else\r
1189                         {\r
1190                                 #region [ (B) その他の場合 ]\r
1191                                 //-----------------\r
1192                                 if( this.tx曲名バー[ (int) type ] != null )\r
1193                                         this.tx曲名バー[ (int) type ].t2D描画( CDTXMania.app.Device, x, y, new Rectangle( 0, 0, 64, 32 ) );               // ヘサキ\r
1194                                 x += 64;\r
1195 \r
1196                                 var rc = new Rectangle( 0, 32, 64, 32 );\r
1197                                 while( x < 640 )\r
1198                                 {\r
1199                                         if( this.tx曲名バー[ (int) type ] != null )\r
1200                                                 this.tx曲名バー[ (int) type ].t2D描画( CDTXMania.app.Device, x, y, rc );  // 胴体;64pxずつ横につなげていく。\r
1201                                         x += 64;\r
1202                                 }\r
1203                                 //-----------------\r
1204                                 #endregion\r
1205                         }\r
1206                 }\r
1207                 private void t曲名バーの生成( int nバー番号, string str曲名, Color color )\r
1208                 {\r
1209                         if( nバー番号 < 0 || nバー番号 > 12 )\r
1210                                 return;\r
1211 \r
1212                         try\r
1213                         {\r
1214                                 SizeF sz曲名;\r
1215 \r
1216                                 #region [ 曲名表示に必要となるサイズを取得する。]\r
1217                                 //-----------------\r
1218                                 using( var bmpDummy = new Bitmap( 1, 1 ) )\r
1219                                 {\r
1220                                         var g = Graphics.FromImage( bmpDummy );\r
1221                                         g.PageUnit = GraphicsUnit.Pixel;\r
1222                                         sz曲名 = g.MeasureString( str曲名, this.ft曲リスト用フォント );\r
1223                                 }\r
1224                                 //-----------------\r
1225                                 #endregion\r
1226 \r
1227                                 int n最大幅px = 392;\r
1228                                 int height = 25;\r
1229                                 int width = (int) ( ( sz曲名.Width + 2 ) * 0.5f );\r
1230                                 if( width > ( CDTXMania.app.Device.Capabilities.MaxTextureWidth / 2 ) )\r
1231                                         width = CDTXMania.app.Device.Capabilities.MaxTextureWidth / 2;  // 右端断ち切れ仕方ないよね\r
1232 \r
1233                                 float f拡大率X = ( width <= n最大幅px ) ? 0.5f : ( ( (float) n最大幅px / (float) width ) * 0.5f );     // 長い文字列は横方向に圧縮。\r
1234 \r
1235                                 using( var bmp = new Bitmap( width * 2, height * 2, PixelFormat.Format32bppArgb ) )             // 2倍(面積4倍)のBitmapを確保。(0.5倍で表示する前提。)\r
1236                                 using( var g = Graphics.FromImage( bmp ) )\r
1237                                 {\r
1238                                         float y = ( ( (float) bmp.Height ) / 2f ) - ( ( CDTXMania.ConfigIni.n選曲リストフォントのサイズdot * 2f ) / 2f );\r
1239                                         g.DrawString( str曲名, this.ft曲リスト用フォント, new SolidBrush( this.color文字影 ), (float) 2f, (float) ( y + 2f ) );\r
1240                                         g.DrawString( str曲名, this.ft曲リスト用フォント, new SolidBrush( color ), 0f, y );\r
1241 \r
1242                                         CDTXMania.t安全にDisposeする( ref this.stバー情報[ nバー番号 ].txタイトル名 );\r
1243 \r
1244                                         this.stバー情報[ nバー番号 ].txタイトル名 = new CTexture( CDTXMania.app.Device, bmp, CDTXMania.TextureFormat );\r
1245                                         this.stバー情報[ nバー番号 ].txタイトル名.vc拡大縮小倍率 = new Vector3( f拡大率X, 0.5f, 1f );\r
1246                                 }\r
1247                         }\r
1248                         catch( CTextureCreateFailedException )\r
1249                         {\r
1250                                 Trace.TraceError( "曲名テクスチャの作成に失敗しました。[{0}]", str曲名 );\r
1251                                 this.stバー情報[ nバー番号 ].txタイトル名 = null;\r
1252                         }\r
1253                 }\r
1254                 private void tアイテム数の描画()\r
1255                 {\r
1256                         string s = nCurrentPosition.ToString() + "/" + nNumOfItems.ToString();\r
1257                         int x = 639 - 8;\r
1258                         int y = 362;\r
1259 \r
1260                         for ( int p = s.Length - 1; p >= 0; p-- )\r
1261                         {\r
1262                                 tアイテム数の描画・1桁描画( x, y, s[ p ] );\r
1263                                 x -= 8;\r
1264                         }\r
1265                 }\r
1266                 private void tアイテム数の描画・1桁描画( int x, int y, char s数値 )\r
1267                 {\r
1268                         int dx, dy;\r
1269                         if ( s数値 == '/' )\r
1270                         {\r
1271                                 dx = 48;\r
1272                                 dy = 0;\r
1273                         }\r
1274                         else\r
1275                         {\r
1276                                 int n = (int) s数値 - (int) '0';\r
1277                                 dx = ( n % 6 ) * 8;\r
1278                                 dy = ( n / 6 ) * 12;\r
1279                         }\r
1280                         if ( this.txアイテム数数字 != null )\r
1281                         {\r
1282                                 this.txアイテム数数字.t2D描画( CDTXMania.app.Device, x, y, new Rectangle( dx, dy, 8, 12 ) );\r
1283                         }\r
1284                 }\r
1285                 //-----------------\r
1286                 #endregion\r
1287         }\r
1288 }\r