OSDN Git Service

#28195 スキン切替の実装。まだConfig.iniのSystem/SkinPathで変更できるだけで、本体動作中の動的な変更はできない。
authoryyagi <yyagi@16f42ceb-6dc6-49c8-ba94-f2d53467949d>
Wed, 2 May 2012 16:00:07 +0000 (16:00 +0000)
committeryyagi <yyagi@16f42ceb-6dc6-49c8-ba94-f2d53467949d>
Wed, 2 May 2012 16:00:07 +0000 (16:00 +0000)
ここしばらくのバージョンアップで追加したテクスチャ画像がなくても最低限の動作はするよう、特定の画像ファイルに限りtry-catchを強化してある。
詳細はチケットを参照のこと。

git-svn-id: http://svn.osdn.jp/svnroot/dtxmania/trunk@386 16f42ceb-6dc6-49c8-ba94-f2d53467949d

DTXManiaプロジェクト/コード/ステージ/02.タイトル/CActEnumSongs.cs
DTXManiaプロジェクト/コード/ステージ/05.選曲/CActSelectPopupMenu.cs
DTXManiaプロジェクト/コード/ステージ/05.選曲/CActSelectQuickConfig.cs
DTXManiaプロジェクト/コード/ステージ/05.選曲/CActSelectShowCurrentPosition.cs
DTXManiaプロジェクト/コード/ステージ/07.演奏/CStage演奏画面共通.cs
DTXManiaプロジェクト/コード/ステージ/07.演奏/ドラム画面/CAct演奏Drumsグラフ.cs
DTXManiaプロジェクト/コード/全体/CConfigIni.cs
DTXManiaプロジェクト/コード/全体/CDTXMania.cs
DTXManiaプロジェクト/コード/全体/CSkin.cs

index 40bdeca..891231b 100644 (file)
@@ -52,7 +52,15 @@ namespace DTXMania
                {\r
                        if ( this.b活性化してない )\r
                                return;\r
-                       this.txNowEnumeratingSongs = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenTitle NowEnumeratingSongs.png" ), false );\r
+                       string pathNowEnumeratingSongs = CSkin.Path( @"Graphics\ScreenTitle NowEnumeratingSongs.png" );\r
+                       if ( File.Exists( pathNowEnumeratingSongs ) )\r
+                       {\r
+                               this.txNowEnumeratingSongs = CDTXMania.tテクスチャの生成( pathNowEnumeratingSongs, false );\r
+                       }\r
+                       else\r
+                       {\r
+                               this.txNowEnumeratingSongs = null;\r
+                       }\r
                        base.OnManagedリソースの作成();\r
                }\r
                public override void OnManagedリソースの解放()\r
index f2810e1..c508270 100644 (file)
@@ -5,6 +5,7 @@ using System.Globalization;
 using System.Text;\r
 using System.Runtime.InteropServices;\r
 using System.Drawing;\r
+using System.IO;\r
 using FDK;\r
 \r
 \r
@@ -198,8 +199,16 @@ namespace DTXMania
                {\r
                        if ( !base.b活性化してない )\r
                        {\r
-                               this.txCursor = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenConfig menu cursor.png" ), false );\r
-                               this.txPopupMenuBackground = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect sort menu background.png" ), false );\r
+                               string pathCursor = CSkin.Path( @"Graphics\ScreenConfig menu cursor.png" );;\r
+                               string pathPopupMenuBackground = CSkin.Path( @"Graphics\ScreenSelect sort menu background.png" );\r
+                               if ( File.Exists ( pathCursor ) )\r
+                               {\r
+                                       this.txCursor = CDTXMania.tテクスチャの生成( pathCursor, false );\r
+                               }\r
+                               if ( File.Exists( pathPopupMenuBackground ) )\r
+                               {\r
+                                       this.txPopupMenuBackground = CDTXMania.tテクスチャの生成( pathPopupMenuBackground, false );\r
+                               }\r
                                base.OnManagedリソースの作成();\r
                        }\r
                }\r
index 36caa44..360bf93 100644 (file)
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Diagnostics;\r
 using System.Text;\r
 using System.Drawing;\r
+using System.IO;\r
 using SlimDX;\r
 using FDK;\r
 \r
@@ -439,8 +440,11 @@ namespace DTXMania
                {\r
                        if( !base.b活性化してない )\r
                        {\r
-                               this.txパネル本体 = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect popup auto settings.png" ), true );\r
-\r
+                               string pathパネル本体 = CSkin.Path( @"Graphics\ScreenSelect popup auto settings.png" );\r
+                               if ( File.Exists( pathパネル本体 ) )\r
+                               {\r
+                                       this.txパネル本体 = CDTXMania.tテクスチャの生成( pathパネル本体, true );\r
+                               }\r
                                base.OnManagedリソースの作成();\r
                        }\r
                }\r
index 354c1ec..06dbb25 100644 (file)
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Text;\r
 using System.Drawing;\r
 using System.Diagnostics;\r
+using System.IO;\r
 using SlimDX;\r
 using FDK;\r
 \r
@@ -34,8 +35,16 @@ namespace DTXMania
                {\r
                        if ( !base.b活性化してない )\r
                        {\r
-                               this.txScrollBar = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect scrollbar.png" ), false );\r
-                               this.txScrollPosition = CDTXMania.tテクスチャの生成( CSkin.Path( @"Graphics\ScreenSelect scrollbar.png" ), false );\r
+                               string pathScrollBar = CSkin.Path( @"Graphics\ScreenSelect scrollbar.png" );\r
+                               string pathScrollPosition = CSkin.Path( @"Graphics\ScreenSelect scrollbar.png" );\r
+                               if ( File.Exists( pathScrollBar ) )\r
+                               {\r
+                                       this.txScrollBar = CDTXMania.tテクスチャの生成( pathScrollBar, false );\r
+                               }\r
+                               if ( File.Exists( pathScrollPosition ) )\r
+                               {\r
+                                       this.txScrollPosition = CDTXMania.tテクスチャの生成( pathScrollPosition, false );\r
+                               }\r
                                base.OnManagedリソースの作成();\r
                        }\r
                }\r
index 0b76b02..754a072 100644 (file)
@@ -272,6 +272,7 @@ namespace DTXMania
                                CDTXMania.DTX.SwapGuitarBassInfos();\r
                        }\r
                        this.sw = new Stopwatch();\r
+                       this.sw2 = new Stopwatch();\r
 //                     this.gclatencymode = GCSettings.LatencyMode;\r
 //                     GCSettings.LatencyMode = GCLatencyMode.LowLatency;      // GCのgen2はせいぜい1演奏辺り1,2回しか発生しないので、ここでわざわざGC gen2は抑止しない\r
                }\r
@@ -544,6 +545,7 @@ namespace DTXMania
 //             protected int nRisky_InitialVar, nRiskyTime;            // #23559 2011.7.28 yyagi → CAct演奏ゲージ共通クラスに隠蔽\r
 \r
                protected Stopwatch sw;         // 2011.6.13 最適化検討用のストップウォッチ\r
+               protected Stopwatch sw2;\r
 //             protected GCLatencyMode gclatencymode;\r
 \r
                protected E判定 e指定時刻からChipのJUDGEを返す( long nTime, CDTX.CChip pChip, int nInputAdjustTime )\r
@@ -695,11 +697,14 @@ namespace DTXMania
                }\r
                protected CDTX.CChip r指定時刻に一番近いChip・ヒット未済問わず不可視考慮( long nTime, int nChannel, int nInputAdjustTime )\r
                {\r
+                       sw2.Start();\r
+//Trace.TraceInformation( "NTime={0}, nChannel={1:x2}", nTime, nChannel );\r
                        nTime += nInputAdjustTime;                                              // #24239 2011.1.23 yyagi InputAdjust\r
 \r
                        int nIndex_InitialPositionSearchingToPast;\r
                        if ( this.n現在のトップChip == -1 )                               // 演奏データとして1個もチップがない場合は\r
                        {\r
+                               sw2.Stop();\r
                                return null;\r
                        }\r
                        int count = CDTXMania.DTX.listChip.Count;\r
@@ -778,11 +783,13 @@ namespace DTXMania
                                }\r
                                else                                                            // 検索対象が未来方向には見つからなかった(しかし過去方向には見つかった)場合\r
                                {\r
+                                       sw2.Stop();\r
                                        return CDTXMania.DTX.listChip[ nIndex_NearestChip_Past ];\r
                                }\r
                        }\r
                        else if ( nIndex_NearestChip_Past < 0 ) // 検索対象が過去方向には見つからなかった(しかし未来方向には見つかった)場合\r
                        {\r
+                               sw2.Stop();\r
                                return CDTXMania.DTX.listChip[ nIndex_NearestChip_Future ];\r
                        }\r
                                                                                                        // 検索対象が過去未来の双方に見つかったなら、より近い方を採用する\r
@@ -792,8 +799,10 @@ namespace DTXMania
                        int nDiffTime_Past   = Math.Abs( (int) ( nTime - nearestChip_Past.n発声時刻ms ) );\r
                        if ( nDiffTime_Future >= nDiffTime_Past )\r
                        {\r
+                               sw2.Stop();\r
                                return nearestChip_Past;\r
                        }\r
+                       sw2.Stop();\r
                        return nearestChip_Future;\r
                }\r
                protected void tサウンド再生( CDTX.CChip rChip, long n再生開始システム時刻ms, E楽器パート part )\r
@@ -1147,12 +1156,15 @@ namespace DTXMania
                }\r
                protected CDTX.CChip r指定時刻に一番近い未ヒットChip( long nTime, int nChannel, int nInputAdjustTime, int n検索範囲時間ms )\r
                {\r
+                       sw2.Start();\r
+//Trace.TraceInformation( "nTime={0}, nChannel={1:x2}, 現在のTop={2}", nTime, nChannel,CDTXMania.DTX.listChip[ this.n現在のトップChip ].n発声時刻ms );\r
                        nTime += nInputAdjustTime;\r
 \r
                        int nIndex_InitialPositionSearchingToPast;\r
                        int nTimeDiff;\r
                        if ( this.n現在のトップChip == -1 )                       // 演奏データとして1個もチップがない場合は\r
                        {\r
+                               sw2.Stop();\r
                                return null;\r
                        }\r
                        int count = CDTXMania.DTX.listChip.Count;\r
@@ -1228,6 +1240,7 @@ namespace DTXMania
                        }\r
                        if ( ( nIndex_NearestChip_Future >= count ) && ( nIndex_NearestChip_Past < 0 ) )        // 検索対象が過去未来どちらにも見つからなかった場合\r
                        {\r
+                               sw2.Stop();\r
                                return null;\r
                        }\r
                        CDTX.CChip nearestChip; // = null;      // 以下のifブロックのいずれかで必ずnearestChipには非nullが代入されるので、null初期化を削除\r
@@ -1259,8 +1272,10 @@ namespace DTXMania
                        nTimeDiff = Math.Abs( (int) ( nTime - nearestChip.n発声時刻ms ) );\r
                        if ( ( n検索範囲時間ms > 0 ) && ( nTimeDiff > n検索範囲時間ms ) )                                   // チップは見つかったが、検索範囲時間外だった場合\r
                        {\r
+                               sw2.Stop();\r
                                return null;\r
                        }\r
+                       sw2.Stop();\r
                        return nearestChip;\r
                }\r
 \r
@@ -1814,7 +1829,7 @@ namespace DTXMania
                                                        if ( configIni.bBGM音を発声する )\r
                                                        {\r
                                                                dTX.tWavの再生停止( this.n最後に再生したBGMの実WAV番号[ pChip.nチャンネル番号 - 0x61 ] );\r
-                                                               dTX.tチップの再生( pChip, CDTXMania.Timer.n前回リセットした時のシステム時刻 + pChip.n発声時刻ms, (int) Eレーン.BGM, dTX.nモニタを考慮した音量( E楽器パート.UNKNOWN ) );\r
+                                                               dTX.tチップの再生( pChip, CDTXMania.Timer.n前回リセットした時のシステム時刻 + pChip.n発声時刻ms, ( int ) Eレーン.BGM, dTX.nモニタを考慮した音量( E楽器パート.UNKNOWN ) );\r
                                                                this.n最後に再生したBGMの実WAV番号[ pChip.nチャンネル番号 - 0x61 ] = pChip.n整数値・内部番号;\r
                                                        }\r
                                                }\r
@@ -2004,14 +2019,17 @@ namespace DTXMania
                protected abstract void t進行描画・チップ・空打ち音設定・ドラム( CConfigIni configIni, ref CDTX dTX, ref CDTX.CChip pChip );\r
                protected void t進行描画・チップアニメ()\r
                {\r
-                       for ( int i = 0; i < 3; i++ )                   // drums: 0-3 gt/bs: 1-3\r
+                       for ( int i = 0; i < 3; i++ )                   // 0=drums, 1=guitar, 2=bass\r
                        {\r
                                if ( this.ctチップ模様アニメ[ i ] != null )\r
                                {\r
                                        this.ctチップ模様アニメ[ i ].t進行Loop();\r
                                }\r
                        }\r
-                       this.ctWailingチップ模様アニメ.t進行Loop();\r
+                       if ( this.ctWailingチップ模様アニメ != null )\r
+                       {\r
+                               this.ctWailingチップ模様アニメ.t進行Loop();\r
+                       }\r
                }\r
 \r
                protected bool t進行描画・フェードイン・アウト()\r
index 0715ade..94f618a 100644 (file)
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Text;\r
 using System.Runtime.InteropServices;\r
 using System.Drawing;\r
+using System.IO;\r
 using SlimDX;\r
 using FDK;\r
 \r
@@ -70,7 +71,11 @@ namespace DTXMania
                {\r
                        if( !base.b活性化してない )\r
                        {\r
-                this.txグラフ = CDTXMania.tテクスチャの生成(CSkin.Path(@"Graphics\ScreenPlay graph.png"));\r
+                               string pathグラフ = CSkin.Path( @"Graphics\ScreenPlay graph.png" );\r
+                               if ( File.Exists( pathグラフ ) )\r
+                               {\r
+                                       this.txグラフ = CDTXMania.tテクスチャの生成( pathグラフ );\r
+                               }\r
                                base.OnManagedリソースの作成();\r
                        }\r
                }\r
index 0bcc554..49dba5a 100644 (file)
@@ -482,6 +482,7 @@ namespace DTXMania
                public int nPoliphonicSounds;                           // #28228 2012.5.1 yyagi レーン毎の最大同時発音数\r
                public bool bバッファ入力を行う;\r
                public bool bIsEnabledSystemMenu;                       // #28200 2012.5.1 yyagi System Menuの使用可否切替\r
+               public string strSkinSubfolder;                         // #28195 2012.5.2 yyagi Skin切替用 System/以下のサブフォルダ名\r
                public bool bConfigIniがないかDTXManiaのバージョンが異なる\r
                {\r
                        get\r
@@ -1016,6 +1017,7 @@ namespace DTXMania
                        this.eBDGroup = EBDGroup.打ち分ける;               // #27029 2012.1.4 from HHPedalとBassPedalのグルーピング\r
                        this.nPoliphonicSounds = 4;                                     // #28228 2012.5.1 yyagi レーン毎の最大同時発音数\r
                        this.bIsEnabledSystemMenu = true;                       // #28200 2012.5.1 yyagi System Menuの利用可否切替(使用可)\r
+                       this.strSkinSubfolder = "";                                     // #28195 2012.5.2 yyagi 使用中のSkinサブフォルダ名\r
                }\r
                public CConfigIni( string iniファイル名 )\r
                        : this()\r
@@ -1072,13 +1074,23 @@ namespace DTXMania
 #endif\r
 \r
                        sw.WriteLine( "; リリースバージョン" );\r
+                       sw.WriteLine( "; Release Version." );\r
                        sw.WriteLine( "Version={0}", CDTXMania.VERSION );\r
                        sw.WriteLine();\r
                        sw.WriteLine( "; 演奏データの格納されているフォルダへのパス。" );\r
                        sw.WriteLine( @"; セミコロン(;)で区切ることにより複数のパスを指定できます。(例: d:\DTXFiles1\;e:\DTXFiles2\)" );\r
+                       sw.WriteLine( "; Pathes for DTX data." );\r
+                       sw.WriteLine( @"; You can specify many pathes separated with semicolon(;). (e.g. d:\DTXFiles1\;e:\DTXFiles2\)" );\r
                        sw.WriteLine( "DTXPath={0}", this.str曲データ検索パス );\r
                        sw.WriteLine();\r
+                       sw.WriteLine( "; 使用するSkinのサブフォルダ名。" );\r
+                       sw.WriteLine( "; System/SkinFiles.Default/Graphics/... などの場合は、SkinPath=SkinFiles.Default を指定します。" );\r
+                       sw.WriteLine( "; Skin subfolder path." );\r
+                       sw.WriteLine( "; e.g. System/SkinFiles.Default/Graphics/... -> Set SkinPath=SkinFiles.Default" );\r
+                       sw.WriteLine( "SkinPath={0}", this.strSkinSubfolder );\r
+                       sw.WriteLine();\r
                        sw.WriteLine( "; 画面モード(0:ウィンドウ, 1:全画面)" );\r
+                       sw.WriteLine( "; Screen mode. (0:Window, 1:Fullscreen)" );\r
                        sw.WriteLine( "FullScreen={0}", this.b全画面モード ? 1 : 0 );\r
             sw.WriteLine();\r
 \r
@@ -1701,7 +1713,11 @@ namespace DTXMania
                                                                                        {\r
                                                                                                this.str曲データ検索パス = str4;\r
                                                                                        }\r
-                                                                                       else if( str3.Equals( "FullScreen" ) )\r
+                                                                                       else if ( str3.Equals( "SkinPath" ) )\r
+                                                                                       {\r
+                                                                                               this.strSkinSubfolder = str4;\r
+                                                                                       }\r
+                                                                                       else if ( str3.Equals( "FullScreen" ) )\r
                                                                                        {\r
                                                                                                this.b全画面モード = C変換.bONorOFF( str4[ 0 ] );\r
                                                                                        }\r
index a35a0fc..6b9904f 100644 (file)
@@ -1476,8 +1476,10 @@ for (int i = 0; i < 3; i++) {
                        Trace.Indent();\r
                        try\r
                        {\r
-                               Skin = new CSkin();\r
-                               Trace.TraceInformation( "スキンの初期化を完了しました。" );\r
+                               Trace.TraceInformation( "初期化開始。{0}", CDTXMania.ConfigIni.strSkinSubfolder );\r
+                               Skin = new CSkin( CDTXMania.ConfigIni.strSkinSubfolder );\r
+                               CDTXMania.ConfigIni.strSkinSubfolder = CSkin.strSkinSubfolder;  // 旧指定のSkinフォルダが消滅していた場合に備える\r
+                               Trace.TraceInformation( "スキンの初期化を完了しました。{0}",CDTXMania.ConfigIni.strSkinSubfolder );\r
                        }\r
                        catch\r
                        {\r
index c77d01c..95341b4 100644 (file)
@@ -2,6 +2,7 @@
 using System.Collections.Generic;\r
 using System.Text;\r
 using System.IO;\r
+using System.Diagnostics;\r
 using FDK;\r
 \r
 namespace DTXMania\r
@@ -266,22 +267,22 @@ namespace DTXMania
        \r
                // プロパティ\r
 \r
-               public Cシステムサウンド bgmオプション画面;\r
-               public Cシステムサウンド bgmコンフィグ画面;\r
-               public Cシステムサウンド bgm起動画面;\r
-               public Cシステムサウンド bgm選曲画面;\r
-               public Cシステムサウンド soundSTAGEFAILED音;\r
-               public Cシステムサウンド soundカーソル移動音;\r
-               public Cシステムサウンド soundゲーム開始音;\r
-               public Cシステムサウンド soundゲーム終了音;\r
-               public Cシステムサウンド soundステージクリア音;\r
-               public Cシステムサウンド soundタイトル音;\r
-               public Cシステムサウンド soundフルコンボ音;\r
-               public Cシステムサウンド sound歓声音;\r
-               public Cシステムサウンド sound曲読込開始音;\r
-               public Cシステムサウンド sound決定音;\r
-               public Cシステムサウンド sound取消音;\r
-               public Cシステムサウンド sound変更音;\r
+               public Cシステムサウンド bgmオプション画面 = null;\r
+               public Cシステムサウンド bgmコンフィグ画面 = null;\r
+               public Cシステムサウンド bgm起動画面 = null;\r
+               public Cシステムサウンド bgm選曲画面 = null;\r
+               public Cシステムサウンド soundSTAGEFAILED音 = null;\r
+               public Cシステムサウンド soundカーソル移動音 = null;\r
+               public Cシステムサウンド soundゲーム開始音 = null;\r
+               public Cシステムサウンド soundゲーム終了音 = null;\r
+               public Cシステムサウンド soundステージクリア音 = null;\r
+               public Cシステムサウンド soundタイトル音 = null;\r
+               public Cシステムサウンド soundフルコンボ音 = null;\r
+               public Cシステムサウンド sound歓声音 = null;\r
+               public Cシステムサウンド sound曲読込開始音 = null;\r
+               public Cシステムサウンド sound決定音 = null;\r
+               public Cシステムサウンド sound取消音 = null;\r
+               public Cシステムサウンド sound変更音 = null;\r
                public readonly int nシステムサウンド数 = 16;\r
                public Cシステムサウンド this[ Eシステムサウンド sound ]\r
                {\r
@@ -398,11 +399,55 @@ namespace DTXMania
                        }\r
                }\r
 \r
+               public string[] strSkinSubfolders = null;               // List<string>だとignoreCaseな検索が面倒なので、配列に逃げる :-)\r
+               public static string strSkinSubfolder = null;\r
 \r
                // コンストラクタ\r
-\r
+               public CSkin( string _strSkinSubfolder )\r
+               {\r
+                       strSkinSubfolder = _strSkinSubfolder;\r
+                       ReloadSkinPaths();\r
+                       Trace.TraceInformation( "SkinPath設定: {0}", strSkinSubfolder );\r
+                       ReloadSkin();\r
+               }\r
                public CSkin()\r
                {\r
+                       ReloadSkinPaths();\r
+                       Trace.TraceInformation( "SkinPath設定: {0}", strSkinSubfolder );\r
+                       ReloadSkin();\r
+                       //this.soundカーソル移動音       = new Cシステムサウンド( @"Sounds\Move.ogg",                    false, false, false );\r
+                       //this.sound決定音                   = new Cシステムサウンド( @"Sounds\Decide.ogg",                  false, false, false );\r
+                       //this.sound変更音                   = new Cシステムサウンド( @"Sounds\Change.ogg",                  false, false, false );\r
+                       //this.sound取消音                   = new Cシステムサウンド( @"Sounds\Cancel.ogg",                  false, false, true  );\r
+                       //this.sound歓声音                   = new Cシステムサウンド( @"Sounds\Audience.ogg",                false, false, true  );\r
+                       //this.soundSTAGEFAILED音              = new Cシステムサウンド( @"Sounds\Stage failed.ogg",    false, true,  true  );\r
+                       //this.soundゲーム開始音          = new Cシステムサウンド( @"Sounds\Game start.ogg",              false, false, false );\r
+                       //this.soundゲーム終了音          = new Cシステムサウンド( @"Sounds\Game end.ogg",                false, true,  false );\r
+                       //this.soundステージクリア音    = new Cシステムサウンド( @"Sounds\Stage clear.ogg",             false, true,  true  );\r
+                       //this.soundフルコンボ音          = new Cシステムサウンド( @"Sounds\Full combo.ogg",              false, false, true  );\r
+                       //this.sound曲読込開始音          = new Cシステムサウンド( @"Sounds\Now loading.ogg",             false, true,  true  );\r
+                       //this.soundタイトル音             = new Cシステムサウンド( @"Sounds\Title.ogg",                   false, true,  false );\r
+                       //this.bgm起動画面                  = new Cシステムサウンド( @"Sounds\Setup BGM.ogg",               true,  true,  false );\r
+                       //this.bgmオプション画面         = new Cシステムサウンド( @"Sounds\Option BGM.ogg",              true,  true,  false );\r
+                       //this.bgmコンフィグ画面         = new Cシステムサウンド( @"Sounds\Config BGM.ogg",              true,  true,  false );\r
+                       //this.bgm選曲画面                  = new Cシステムサウンド( @"Sounds\Select BGM.ogg",              true,  true,  false );\r
+               }\r
+\r
+               /// <summary>\r
+               /// Skin(Sounds)を再読込する。\r
+               /// あらかじめstrSkinSubfolderを適切に設定しておくこと。\r
+               /// その後、ReloadSkinPaths()を実行し、strSkinSubfolderの正当性を確認した上で、本メソッドを呼び出すこと。\r
+               /// </summary>\r
+               private void ReloadSkin()\r
+               {\r
+                       for ( int i = 0; i < nシステムサウンド数; i++ )\r
+                       {\r
+                               if ( this[ i ] != null && this[i].b読み込み成功 )\r
+                               {\r
+                                       this[ i ].t停止する();\r
+                                       this[ i ].Dispose();\r
+                               }\r
+                       }\r
                        this.soundカーソル移動音 = new Cシステムサウンド( @"Sounds\Move.ogg",                    false, false, false );\r
                        this.sound決定音                     = new Cシステムサウンド( @"Sounds\Decide.ogg",                  false, false, false );\r
                        this.sound変更音                     = new Cシステムサウンド( @"Sounds\Change.ogg",                  false, false, false );\r
@@ -421,12 +466,67 @@ namespace DTXMania
                        this.bgm選曲画面                    = new Cシステムサウンド( @"Sounds\Select BGM.ogg",              true,  true,  false );\r
                }\r
 \r
+               /// <summary>\r
+               /// Skinの一覧を再取得する。\r
+               /// System/SkinFiles.*****/Graphics (やSounds/) というフォルダ構成を想定している。\r
+               /// もし再取得の結果、現在使用中のSkinのパス(strSkinSubfloder)が消えていた場合は、\r
+               /// 以下の優先順位で存在確認の上strSkinSubfolderを再設定する。\r
+               /// 1. System/SkinFiles.Default/\r
+               /// 2. System/SkinFiles.*****/ で最初にenumerateされたもの\r
+               /// 3. System/ (従来互換)\r
+               /// </summary>\r
+               public void ReloadSkinPaths()\r
+               {\r
+                       string path;\r
+                       #region [ まず System/SkinFiles.*** をenumerateする ]\r
+                       path = System.IO.Path.Combine( CDTXMania.strEXEのあるフォルダ, "System" );\r
+                       strSkinSubfolders = System.IO.Directory.GetDirectories( path, "SkinFiles.*" );\r
+                       for ( int i = 0; i < strSkinSubfolders.Length; i++ )\r
+                       {\r
+                               string[] spl = strSkinSubfolders[ i ].Split( System.IO.Path.DirectorySeparatorChar );\r
+                               strSkinSubfolders[ i ] = spl[ spl.Length - 1 ];         // subfolder名から、~~/System/ までの部分を削除\r
+                               Trace.TraceInformation( "SkinPath検出: {0}", strSkinSubfolders[ i ] );\r
+                       }\r
+                       Array.Sort( strSkinSubfolders );        // BinarySearch実行前にSortが必要\r
+                       #endregion\r
+                       #region [ 次に、カレントのSkinパスが存在するか調べる。あれば終了。]\r
+                       if ( Array.BinarySearch( strSkinSubfolders, strSkinSubfolder, StringComparer.InvariantCultureIgnoreCase ) >= 0 )\r
+                               return;\r
+                       #endregion\r
+                       #region [ カレントのSkinパスが消滅しているので、再設定する。]\r
+                       /// 以下の優先順位で現在使用中のSkinパスを再設定する。\r
+                       /// 1. System/SkinFiles.Default/\r
+                       /// 2. System/SkinFiles.*****/ で最初にenumerateされたもの\r
+                       /// 3. System/ (従来互換)\r
+                       #region [ System/SkinFiles.Default/ があるなら、そこにカレントSkinパスを設定する]\r
+                       if ( Array.BinarySearch( strSkinSubfolders, "SkinFiles.Default", StringComparer.InvariantCultureIgnoreCase ) >= 0 )\r
+                       {\r
+                               strSkinSubfolder = "SkinFiles.Default";\r
+                               return;\r
+                       }\r
+                       #endregion\r
+                       #region [ System/SkinFiles.*****/ で最初にenumerateされたものを、カレントSkinパスに再設定する ]\r
+                       if ( strSkinSubfolders.Length > 0 )\r
+                       {\r
+                               strSkinSubfolder = strSkinSubfolders[ 0 ];\r
+                               return;\r
+                       }\r
+                       #endregion\r
+                       #region [ System/ に、カレントSkinパスを再設定する。]\r
+                       strSkinSubfolder = "";                  // ""にすることで、結果的に System/ 相当の相対パスになる。\r
+                       #endregion\r
+                       #endregion\r
+               }\r
 \r
                // メソッド\r
 \r
                public static string Path( string strファイルの相対パス )\r
                {\r
-                       return ( CDTXMania.strEXEのあるフォルダ + @"System\" + strファイルの相対パス );\r
+                       string path;\r
+                       path = System.IO.Path.Combine( CDTXMania.strEXEのあるフォルダ, "System" );\r
+                       path = System.IO.Path.Combine( path, strSkinSubfolder );\r
+                       path = System.IO.Path.Combine( path, strファイルの相対パス );\r
+                       return path;\r
                }\r
                \r
                #region [ IDisposable 実装 ]\r