<Compile Include="コード\全体\CDTXMania.cs" />\r
<Compile Include="コード\全体\CDTXVersion.cs" />\r
<Compile Include="コード\全体\CPad.cs" />\r
+ <Compile Include="コード\全体\CPreviewMagnifier.cs" />\r
+ <Compile Include="コード\全体\CPrivateFastFont.cs" />\r
+ <Compile Include="コード\全体\CPrivateFont.cs" />\r
+ <Compile Include="コード\全体\CScale.cs" />\r
<Compile Include="コード\全体\CSkin.cs" />\r
<Compile Include="コード\全体\C定数.cs" />\r
<Compile Include="コード\全体\C文字コンソール.cs" />\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using FDK;\r
+\r
+namespace DTXMania\r
+{\r
+ internal class CAct演奏スクロール速度 : CActivity\r
+ {\r
+ // プロパティ\r
+\r
+ public STDGBVALUE<double> db現在の譜面スクロール速度;\r
+\r
+\r
+ // コンストラクタ\r
+\r
+ public CAct演奏スクロール速度()\r
+ {\r
+ base.b活性化してない = true;\r
+ }\r
+\r
+\r
+ // CActivity 実装\r
+\r
+ public override void On活性化()\r
+ {\r
+ for( int i = 0; i < 3; i++ )\r
+ {\r
+ this.db現在の譜面スクロール速度[ i ] = (double) CDTXMania.ConfigIni.n譜面スクロール速度[ i ];\r
+ this.n速度変更制御タイマ[ i ] = -1;\r
+ }\r
+ base.On活性化();\r
+ }\r
+ public override unsafe int On進行描画()\r
+ {\r
+ if( !base.b活性化してない )\r
+ {\r
+ if( base.b初めての進行描画 )\r
+ {\r
+ this.n速度変更制御タイマ.Drums = this.n速度変更制御タイマ.Guitar = this.n速度変更制御タイマ.Bass = CSound管理.rc演奏用タイマ.n現在時刻;\r
+ base.b初めての進行描画 = false;\r
+ }\r
+ long n現在時刻 = CSound管理.rc演奏用タイマ.n現在時刻;\r
+ for( int i = 0; i < 3; i++ )\r
+ {\r
+ const double db譜面スクロールスピード = (double) CDTXMania.ConfigIni.n譜面スクロール速度[ i ];\r
+ if( n現在時刻 < this.n速度変更制御タイマ[ i ] )\r
+ {\r
+ this.n速度変更制御タイマ[ i ] = n現在時刻;\r
+ }\r
+ while( ( n現在時刻 - this.n速度変更制御タイマ[ i ] ) >= 2 )\r
+ {\r
+ if( this.db現在の譜面スクロール速度[ i ] < db譜面スクロールスピード ) // Config.iniのスクロール速度を変えると、それに追いつくように実画面のスクロール速度を変える\r
+ {\r
+ this.db現在の譜面スクロール速度[ i ] += 0.012;\r
+\r
+ if( this.db現在の譜面スクロール速度[ i ] > db譜面スクロールスピード )\r
+ {\r
+ this.db現在の譜面スクロール速度[ i ] = db譜面スクロールスピード;\r
+ }\r
+ }\r
+ else if ( this.db現在の譜面スクロール速度[ i ] > db譜面スクロールスピード )\r
+ {\r
+ this.db現在の譜面スクロール速度[ i ] -= 0.012;\r
+\r
+ if( this.db現在の譜面スクロール速度[ i ] < db譜面スクロールスピード )\r
+ {\r
+ this.db現在の譜面スクロール速度[ i ] = db譜面スクロールスピード;\r
+ }\r
+ }\r
+ this.n速度変更制御タイマ[ i ] += 2;\r
+ }\r
+ }\r
+ }\r
+ return 0;\r
+ }\r
+\r
+\r
+ // その他\r
+\r
+ #region [ private ]\r
+ //-----------------\r
+ private STDGBVALUE<long> n速度変更制御タイマ;\r
+ //-----------------\r
+ #endregion\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using System.Diagnostics;\r
+\r
+namespace DTXMania\r
+{\r
+ /// <summary>\r
+ /// 判定ライン関係の座標処理をまとめたクラス\r
+ /// </summary>\r
+ internal class C演奏判定ライン座標共通\r
+ {\r
+ /// <summary>\r
+ /// 判定ラインのy座標\r
+ /// </summary>\r
+ private STDGBVALUE<int>[,,] n判定ラインY座標元データ = null; // 補正無しの時の座標データ\r
+ private STDGBVALUE<int>[,,] n演奏RGBボタンY座標元データ = null;\r
+\r
+ /// <summary>\r
+ /// 表示位置の補正データ\r
+ /// 初期化は外部から行うこと。\r
+ /// </summary>\r
+ public STDGBVALUE<int> nJudgeLinePosY_delta;\r
+\r
+ /// <summary>\r
+ /// 判定ライン表示位置を、Vシリーズ互換にするかどうか。\r
+ /// 設定は外部から行うこと。\r
+ /// </summary>\r
+ public STDGBVALUE<E判定位置> n判定位置;\r
+\r
+ /// <summary>\r
+ /// コンストラクタ(座標値の初期化)\r
+ /// </summary>\r
+ public C演奏判定ライン座標共通()\r
+ {\r
+ n判定ラインY座標元データ = new STDGBVALUE<int>[ 2, 2, 2 ];\r
+ #region [ 判定ライン座標の初期化]\r
+ // Normal, Drums画面, 判定ライン\r
+ n判定ラインY座標元データ[ 0, 0, 0 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 0, 0, 0 ].Guitar = 95;\r
+ n判定ラインY座標元データ[ 0, 0, 0 ].Bass = 95;\r
+ // Reverse, Drums画面, 判定ライン\r
+ n判定ラインY座標元データ[ 1, 0, 0 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 1, 0, 0 ].Guitar = 374;\r
+ n判定ラインY座標元データ[ 1, 0, 0 ].Bass = 374;\r
+ // Normal, Drums画面, Wailing枠\r
+ n判定ラインY座標元データ[ 0, 0, 1 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 0, 0, 1 ].Guitar = 69;\r
+ n判定ラインY座標元データ[ 0, 0, 1 ].Bass = 69;\r
+ // Reverse, Drums画面, Wailing枠\r
+ n判定ラインY座標元データ[ 1, 0, 1 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 1, 0, 1 ].Guitar = 350;\r
+ n判定ラインY座標元データ[ 1, 0, 1 ].Bass = 350;\r
+\r
+ // Normal, GR画面, 判定ライン\r
+ n判定ラインY座標元データ[ 0, 1, 0 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 0, 1, 0 ].Guitar = 40;\r
+ n判定ラインY座標元データ[ 0, 1, 0 ].Bass = 40;\r
+ // Reverse, GR画面, 判定ライン\r
+ n判定ラインY座標元データ[ 1, 1, 0 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 1, 1, 0 ].Guitar = 369;\r
+ n判定ラインY座標元データ[ 1, 1, 0 ].Bass = 369;\r
+ // Normal, GR画面, Wailing枠\r
+ n判定ラインY座標元データ[ 0, 1, 1 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 0, 1, 1 ].Guitar = 11;\r
+ n判定ラインY座標元データ[ 0, 1, 1 ].Bass = 11;\r
+ // Reverse, GR画面, Wailing枠\r
+ n判定ラインY座標元データ[ 1, 1, 1 ].Drums = 0; //未使用\r
+ n判定ラインY座標元データ[ 1, 1, 1 ].Guitar = 340;\r
+ n判定ラインY座標元データ[ 1, 1, 1 ].Bass = 340;\r
+ #endregion\r
+\r
+ n演奏RGBボタンY座標元データ = new STDGBVALUE<int>[ 2, 2, 2 ];\r
+ #region [ RGBボタン座標の初期化]\r
+ // Normal, Drums画面, RGBボタン\r
+ n演奏RGBボタンY座標元データ[ 0, 0, 0 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 0, 0, 0 ].Guitar = 57;\r
+ n演奏RGBボタンY座標元データ[ 0, 0, 0 ].Bass = 57;\r
+ // Reverse, Drums画面, RGBボタン\r
+ n演奏RGBボタンY座標元データ[ 1, 0, 0 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 1, 0, 0 ].Guitar = 57;\r
+ n演奏RGBボタンY座標元データ[ 1, 0, 0 ].Bass = 57;\r
+ // Normal, Drums画面, RGBボタン(Vシリーズ)\r
+ n演奏RGBボタンY座標元データ[ 0, 0, 1 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 0, 0, 1 ].Guitar = 107;\r
+ n演奏RGBボタンY座標元データ[ 0, 0, 1 ].Bass = 107;\r
+ // Reverse, Drums画面, RGBボタン(Vシリーズ)\r
+ n演奏RGBボタンY座標元データ[ 1, 0, 1 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 1, 0, 1 ].Guitar = 107;\r
+ n演奏RGBボタンY座標元データ[ 1, 0, 1 ].Bass = 107;\r
+\r
+ // Normal, GR画面, RGBボタン\r
+ n演奏RGBボタンY座標元データ[ 0, 1, 0 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 0, 1, 0 ].Guitar = 3;\r
+ n演奏RGBボタンY座標元データ[ 0, 1, 0 ].Bass = 3;\r
+ // Reverse, GR画面, RGBボタン\r
+ n演奏RGBボタンY座標元データ[ 1, 1, 0 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 1, 1, 0 ].Guitar = 3;\r
+ n演奏RGBボタンY座標元データ[ 1, 1, 0 ].Bass = 3;\r
+ // Normal, GR画面, RGBボタン(Vシリーズ)\r
+ n演奏RGBボタンY座標元データ[ 0, 1, 1 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 0, 1, 1 ].Guitar = 44;\r
+ n演奏RGBボタンY座標元データ[ 0, 1, 1 ].Bass = 44;\r
+ // Reverse, GR画面, RGBボタン(Vシリーズ)\r
+ n演奏RGBボタンY座標元データ[ 1, 1, 1 ].Drums = 0; // 未使用\r
+ n演奏RGBボタンY座標元データ[ 1, 1, 1 ].Guitar = 44;\r
+ n演奏RGBボタンY座標元データ[ 1, 1, 1 ].Bass = 44;\r
+ #endregion\r
+\r
+ n判定位置 = new STDGBVALUE<E判定位置>();\r
+ n判定位置.Drums = E判定位置.標準;\r
+ n判定位置.Guitar = E判定位置.標準;\r
+ n判定位置.Bass = E判定位置.標準;\r
+\r
+ // 補正値は、Normal/Reverse, Drums/GR画面共通\r
+ nJudgeLinePosY_delta.Drums = 0;\r
+ nJudgeLinePosY_delta.Guitar = 0;\r
+ nJudgeLinePosY_delta.Bass = 0;\r
+ }\r
+\r
+\r
+ \r
+ /// <summary>\r
+ /// 判定ラインのY座標を返す。とりあえずGuitar/Bassのみ対応。\r
+ /// </summary>\r
+ /// <param name="eInst">E楽器パート</param>\r
+ /// <param name="bGRmode">GRmodeか否か</param>\r
+ /// <param name="bReverse">Reverseか否か</param>\r
+ /// <returns></returns>\r
+ public int n判定ラインY座標( E楽器パート eInst, bool bGRmode, bool bReverse )\r
+ {\r
+ return n判定ラインY座標( eInst, bGRmode, bReverse, false );\r
+ }\r
+\r
+ public int n判定ラインY座標( E楽器パート eInst, bool bGRmode, bool bReverse, bool bWailingFrame )\r
+ {\r
+ return n判定ラインY座標( eInst, bGRmode, bReverse, bWailingFrame, false );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 判定ラインのY座標を返す。とりあえずGuitar/Bassのみ対応。\r
+ /// </summary>\r
+ /// <param name="eInst">E楽器パート</param>\r
+ /// <param name="bGRmode">GRmodeか否か</param>\r
+ /// <param name="bReverse">Reverseか否か</param>\r
+ /// <param name="bWailingFrame">Wailing枠の座標か、判定ラインの座標か</param>\r
+ /// <param name="b補正あり">プレーヤーのライン表示位置補正情報を加えるかどうか</param>\r
+ /// <returns></returns>\r
+ public int n判定ラインY座標( E楽器パート eInst, bool bGRmode, bool bReverse, bool bWailingFrame, bool b補正あり )\r
+ {\r
+ if ( eInst == E楽器パート.DRUMS )\r
+ {\r
+ throw new NotImplementedException();\r
+ }\r
+ else if ( eInst == E楽器パート.UNKNOWN )\r
+ {\r
+ throw new ArgumentOutOfRangeException();\r
+ }\r
+ else\r
+ {\r
+ int nReverse = bReverse ? 1 : 0;\r
+ int nGRmode = bGRmode ? 1 : 0;\r
+ int nWailing = bWailingFrame ? 1 : 0;\r
+ int nInst = (int) eInst;\r
+ int ret = this.n判定ラインY座標元データ[ nReverse, nGRmode, nWailing ][ nInst ]; // 補正無しの値\r
+ if ( bReverse )\r
+ {\r
+ if ( n判定位置[ nInst ] == E判定位置.Lower ) ret += 13;\r
+ if ( b補正あり ) ret += nJudgeLinePosY_delta[ nInst ];\r
+ }\r
+ else\r
+ {\r
+ if ( n判定位置[ nInst ] == E判定位置.Lower ) ret += 52;\r
+ if ( b補正あり ) ret -= nJudgeLinePosY_delta[ nInst ];\r
+ }\r
+ return ret;\r
+ }\r
+ }\r
+\r
+ public int n演奏RGBボタンY座標( E楽器パート eInst, bool bGRmode, bool bReverse )\r
+ {\r
+ if ( eInst == E楽器パート.DRUMS )\r
+ {\r
+ throw new NotImplementedException();\r
+ }\r
+ else if ( eInst == E楽器パート.UNKNOWN )\r
+ {\r
+ throw new ArgumentOutOfRangeException();\r
+ }\r
+ else\r
+ {\r
+ int nInst = (int) eInst;\r
+ int nGRmode = bGRmode ? 1 : 0;\r
+ int nReverse = bReverse ? 1 : 0;\r
+ int nVseries = (int) n判定位置[ nInst ];\r
+ int ret = n演奏RGBボタンY座標元データ[ nReverse, nGRmode, nVseries ][ nInst ]; // 補正無しの値\r
+\r
+ return ret;\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using System.Diagnostics;\r
+using System.IO;\r
+using System.Threading;\r
+using FDK;\r
+\r
+\r
+namespace DTXMania\r
+{\r
+ public class CDTXVmode\r
+ {\r
+ public enum ECommand\r
+ {\r
+ Stop,\r
+ Play,\r
+ Preview\r
+ }\r
+\r
+ /// <summary>\r
+ /// DTXVモードかどうか\r
+ /// </summary>\r
+ public bool Enabled\r
+ {\r
+ get;\r
+ set;\r
+ }\r
+\r
+ /// <summary>\r
+ /// プレビューサウンドの再生が発生した\r
+ /// </summary>\r
+ public bool Preview\r
+ {\r
+ get;\r
+ set;\r
+ }\r
+\r
+ /// <summary>\r
+ /// 外部から再指示が発生したか\r
+ /// </summary>\r
+ public bool Refreshed\r
+ {\r
+ get;\r
+ set;\r
+ }\r
+\r
+ /// <summary>\r
+ /// 演奏開始小節番号\r
+ /// </summary>\r
+ public int nStartBar\r
+ {\r
+ get;\r
+ set;\r
+ }\r
+\r
+ /// <summary>\r
+ /// DTXファイルの再読み込みが必要かどうか\r
+ /// </summary>\r
+ public bool NeedReload\r
+ {\r
+ get;\r
+ private set;\r
+// private set; // 本来はprivate setにすべきだが、デバッグが簡単になるので、しばらくはprivateなしのままにする。\r
+ }\r
+\r
+ /// <summary>\r
+ /// DTXCからのコマンド\r
+ /// </summary>\r
+ public ECommand Command\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+\r
+ public ESoundDeviceType soundDeviceType\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public int nASIOdevice\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ /// <summary>\r
+ /// 前回からサウンドデバイスが変更されたか\r
+ /// </summary>\r
+ public bool ChangedSoundDevice\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+\r
+ public string filename\r
+ {\r
+ get\r
+ {\r
+ return last_path;\r
+ }\r
+ }\r
+\r
+ public string previewFilename\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public int previewVolume\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public int previewPan\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public bool GRmode\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public bool lastGRmode\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public bool TimeStretch\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public bool lastTimeStretch\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public bool VSyncWait\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+ public bool lastVSyncWait\r
+ {\r
+ get;\r
+ private set;\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// コンストラクタ\r
+ /// </summary>\r
+ public CDTXVmode()\r
+ {\r
+ this.last_path = "";\r
+ this.last_timestamp = DateTime.MinValue;\r
+ this.Enabled = false;\r
+ this.nStartBar = 0;\r
+ this.Refreshed = false;\r
+ this.NeedReload = false;\r
+ this.previewFilename = "";\r
+ this.GRmode = false;\r
+ this.lastGRmode = false;\r
+ this.TimeStretch = false;\r
+ this.lastTimeStretch = false;\r
+ this.VSyncWait = true;\r
+ this.lastVSyncWait = true;\r
+ }\r
+\r
+ /// <summary>\r
+ /// DTXファイルのリロードが必要かどうか判定する\r
+ /// </summary>\r
+ /// <param name="filename">DTXファイル名</param>\r
+ /// <returns>再読込が必要ならtrue</returns>\r
+ /// <remarks>プロパティNeedReloadにも結果が入る</remarks>\r
+ /// <remarks>これを呼び出すたびに、Refreshedをtrueにする</remarks>\r
+ /// <exception cref="FileNotFoundException"></exception>\r
+ public bool bIsNeedReloadDTX( string filename )\r
+ {\r
+ if ( !File.Exists( filename ) ) // 指定したファイルが存在しないなら例外終了\r
+ {\r
+ Trace.TraceError( "ファイルが見つかりません。({0})", filename );\r
+ throw new FileNotFoundException();\r
+ //return false;\r
+ }\r
+\r
+ this.Refreshed = true;\r
+\r
+ // 前回とファイル名が異なるか、タイムスタンプが更新されているか、\r
+ // GRmode等の設定を変更したなら、DTX要更新\r
+ DateTime current_timestamp = File.GetLastWriteTime( filename );\r
+ if ( last_path != filename || current_timestamp > last_timestamp ||\r
+ this.lastGRmode != this.GRmode || this.lastTimeStretch != this.TimeStretch || this.lastVSyncWait != this.VSyncWait )\r
+ {\r
+ this.last_path = filename;\r
+ this.last_timestamp = current_timestamp;\r
+ this.lastGRmode = this.GRmode;\r
+ this.lastTimeStretch = this.TimeStretch;\r
+ this.lastVSyncWait = this.VSyncWait;\r
+\r
+ this.NeedReload = true;\r
+ return true;\r
+ }\r
+ this.NeedReload = false;\r
+ return false;\r
+ }\r
+\r
+ /// <summary>\r
+ /// \r
+ /// </summary>\r
+ /// <param name="arg"></param>\r
+ /// <param name="nStartBar"></param>\r
+ /// <param name="command"></param>\r
+ /// <returns>DTXV用の引数であればtrue</returns>\r
+ /// <remarks>内部でEnabled, nStartBar, Command, NeedReload, filename, last_path, last_timestampを設定する</remarks>\r
+ public bool ParseArguments( string arg )\r
+ {\r
+ bool ret = false, analyzing = true;\r
+ this.nStartBar = 0;\r
+\r
+ if ( arg != null ) \r
+ {\r
+ while ( analyzing )\r
+ {\r
+ if ( arg == "" )\r
+ {\r
+ analyzing = false;\r
+ }\r
+ else if ( arg.StartsWith( "-V", StringComparison.OrdinalIgnoreCase ) ) // サウンド再生\r
+ {\r
+ // -Vvvv,ppp,"filename"の形式。 vvv=volume, ppp=pan.\r
+ this.Enabled = true;\r
+ this.Command = ECommand.Preview;\r
+ this.Refreshed = true;\r
+ ret = true;\r
+ arg = arg.Substring( 2 );\r
+\r
+ int pVol = arg.IndexOf( ',' ); //Trace.TraceInformation( "pVol=" + pVol );\r
+ string strVol = arg.Substring( 0, pVol ); //Trace.TraceInformation( "strVol=" + strVol );\r
+ this.previewVolume = Convert.ToInt32( strVol ); //Trace.TraceInformation( "previewVolume=" + previewVolume );\r
+ int pPan = arg.IndexOf( ',', pVol + 1 ); //Trace.TraceInformation( "pPan=" + pPan );\r
+ string strPan = arg.Substring( pVol + 1, pPan - pVol - 1 ); //Trace.TraceInformation( "strPan=" + strPan );\r
+ this.previewPan = Convert.ToInt32( strPan ); //Trace.TraceInformation( "previewPan=" + previewPan );\r
+\r
+ arg = arg.Substring( pPan + 1 );\r
+ arg = arg.Trim( new char[] { '\"' } );\r
+ this.previewFilename = arg;\r
+ analyzing = false;\r
+ }\r
+ // -S -Nxxx filename\r
+ else if ( arg.StartsWith( "-S", StringComparison.OrdinalIgnoreCase ) ) // DTXV再生停止\r
+ {\r
+ this.Enabled = true;\r
+ this.Command = ECommand.Stop;\r
+ this.Refreshed = true;\r
+ ret = true;\r
+ arg = arg.Substring( 2 );\r
+ }\r
+ else if ( arg.StartsWith( "-D", StringComparison.OrdinalIgnoreCase ) )\r
+ {\r
+ // -DW, -DA1など\r
+ arg = arg.Substring( 2 ); // -D を削除\r
+ switch ( arg[ 0 ] )\r
+ {\r
+ #region [ DirectSound ]\r
+ case 'D':\r
+ if ( this.soundDeviceType != ESoundDeviceType.DirectSound )\r
+ {\r
+ this.ChangedSoundDevice = true;\r
+ this.soundDeviceType = ESoundDeviceType.DirectSound;\r
+ }\r
+ else\r
+ {\r
+ this.ChangedSoundDevice = false;\r
+ }\r
+ arg = arg.Substring( 1 );\r
+ break;\r
+ #endregion\r
+ #region [ WASAPI ]\r
+ case 'W':\r
+ if ( this.soundDeviceType != ESoundDeviceType.ExclusiveWASAPI )\r
+ {\r
+ this.ChangedSoundDevice = true;\r
+ this.soundDeviceType = ESoundDeviceType.ExclusiveWASAPI;\r
+ }\r
+ else\r
+ {\r
+ this.ChangedSoundDevice = false;\r
+ }\r
+ arg = arg.Substring( 1 );\r
+ break;\r
+ #endregion\r
+ #region [ ASIO ]\r
+ case 'A':\r
+ if ( this.soundDeviceType != ESoundDeviceType.ASIO )\r
+ {\r
+ this.ChangedSoundDevice = true;\r
+ this.soundDeviceType = ESoundDeviceType.ASIO;\r
+ }\r
+ else\r
+ {\r
+ this.ChangedSoundDevice = false;\r
+ }\r
+ arg = arg.Substring( 1 );\r
+\r
+ int nAsioDev = 0, p = 0;\r
+ while ( true )\r
+ {\r
+ char c = arg[ 0 ];\r
+ if ( '0' <= c && c <= '9' )\r
+ {\r
+ nAsioDev *= 10;\r
+ nAsioDev += c - '0';\r
+ p++;\r
+ arg = arg.Substring( 1 );\r
+ continue;\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ if ( this.nASIOdevice != nAsioDev )\r
+ {\r
+ this.ChangedSoundDevice = true;\r
+ this.nASIOdevice = nAsioDev;\r
+ }\r
+ break;\r
+ #endregion\r
+ }\r
+ #region [ GRmode, TimeStretch, VSyncWait ]\r
+ {\r
+ // Reload判定は、-Nのところで行う\r
+ this.GRmode = ( arg[ 0 ] == 'Y' );\r
+ this.TimeStretch = ( arg[ 1 ] == 'Y' );\r
+ this.VSyncWait = ( arg[ 2 ] == 'Y' );\r
+\r
+ arg = arg.Substring( 3 );\r
+ }\r
+ #endregion\r
+ }\r
+ else if ( arg.StartsWith( "-N", StringComparison.OrdinalIgnoreCase ) )\r
+ {\r
+ this.Enabled = true;\r
+ this.Command = ECommand.Play;\r
+ ret = true;\r
+\r
+ arg = arg.Substring( 2 ); // "-N"を除去\r
+ string[] p = arg.Split( new char[] { ' ' } );\r
+ this.nStartBar = int.Parse( p[ 0 ] ); // 再生開始小節\r
+ if ( this.nStartBar < 0 )\r
+ {\r
+ this.nStartBar = -1;\r
+ }\r
+\r
+ int startIndex = arg.IndexOf( ' ' );\r
+ string filename = arg.Substring( startIndex + 1 ); // 再生ファイル名(フルパス) これで引数が終わっていることを想定\r
+ try\r
+ {\r
+ filename = filename.Trim( new char[] { '\"' } );\r
+ bIsNeedReloadDTX( filename );\r
+ }\r
+ catch // 指定ファイルが存在しない\r
+ {\r
+ }\r
+ arg = "";\r
+ analyzing = false;\r
+ }\r
+ }\r
+ }\r
+string[] s = { "Stop", "Play", "Preview" };\r
+Trace.TraceInformation( "Command: " + s[ (int) this.Command ] );\r
+ return ret;\r
+ }\r
+\r
+ /// <summary>\r
+ /// Viewer関連の設定のみを更新して、Config.iniに書き出す\r
+ /// </summary>\r
+ public void tUpdateConfigIni()\r
+ {\r
+ CConfigIni cc = new CConfigIni();\r
+ string path = CDTXMania.strEXEのあるフォルダ + "Config.ini";\r
+ if ( File.Exists( path ) )\r
+ {\r
+ FileInfo fi = new FileInfo( path );\r
+ if ( fi.Length > 0 ) // Config.iniが0byteだったなら、読み込まない\r
+ {\r
+ try\r
+ {\r
+ cc.tファイルから読み込み( path );\r
+ }\r
+ catch\r
+ {\r
+ //ConfigIni = new CConfigIni(); // 存在してなければ新規生成\r
+ }\r
+ }\r
+ fi = null;\r
+ }\r
+\r
+ cc.nViewerScrollSpeed = CDTXMania.ConfigIni.n譜面スクロール速度;\r
+ cc.bViewerShowDebugStatus = CDTXMania.ConfigIni.b演奏情報を表示する;\r
+ cc.bViewerVSyncWait = CDTXMania.ConfigIni.b垂直帰線待ちを行う;\r
+ cc.bViewerTimeStretch = CDTXMania.ConfigIni.bTimeStretch;\r
+ cc.bViewerDrums有効 = CDTXMania.ConfigIni.bDrums有効;\r
+ cc.bViewerGuitar有効 = CDTXMania.ConfigIni.bGuitar有効;\r
+\r
+ cc.t書き出し( path );\r
+ }\r
+\r
+ private string last_path;\r
+ private DateTime last_timestamp;\r
+\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using System.Diagnostics;\r
+\r
+namespace DTXMania\r
+{\r
+ public class CPreviewMagnifier\r
+ {\r
+ #region [ プロパティ(拡大率等の取得) ]\r
+ /// <summary>\r
+ /// 拡大後のwidth\r
+ /// </summary>\r
+ public int width;\r
+ /// <summary>\r
+ /// 拡大後のheight\r
+ /// </summary>\r
+ public int height;\r
+ /// <summary>\r
+ /// 拡大後のX拡大率\r
+ /// </summary>\r
+ public float magX;\r
+ /// <summary>\r
+ /// 拡大後のY拡大率\r
+ /// </summary>\r
+ public float magY;\r
+\r
+ /// <summary>\r
+ /// プレビュー画像向けの拡大率か(それとも、演奏画面向けの拡大率か)\r
+ /// </summary>\r
+ public bool bIsPreview;\r
+ #endregion\r
+\r
+ #region [ 定数定義 ]\r
+ // 配列の0,1要素はそれぞれ, Preview用, 演奏画面用\r
+ private int[] WIDTH_VGA_SET = { 204, 278 }; // VGA版DTXManiaのプレビュー画像width値\r
+ private int[] HEIGHT_VGA_SET = { 269, 355 }; // VGA版DTXManiaのプレビュー画像height値\r
+ private int[] WIDTH_HD_SET = { 400, 400 }; // HD版DTXManiaのプレビュー画像width値\r
+ private int[] HEIGHT_HD_SET = { 400, 600 }; // 600は仮 // HD版DTXManiaのプレビュー画像height値\r
+ private int[] WIDTH_FHD_LIMIT = { 320, 320 }; // VGA版/FullHD版どちらのプレビュー画像とみなすかのwidth閾値\r
+ private int[] HEIGHT_FHD_LIMIT = { 416, 416 }; // VGA版/FullHD版どちらのプレビュー画像とみなすかのwidth閾値\r
+ private int[] WIDTH_FHD_SET = { (int) ( 204 * Scale.X ), (int) ( 278 * Scale.X ) }; // FHD版DTXManiaのプレビュー画像height値\r
+ private int[] HEIGHT_FHD_SET = { (int) ( 269 * Scale.Y ), (int) ( 355 * Scale.Y ) }; // FHD版DTXManiaのプレビュー画像height値\r
+ #endregion\r
+\r
+ #region [ コンストラクタ ]\r
+ /// <summary>\r
+ /// コンストラクタ\r
+ /// </summary>\r
+ public CPreviewMagnifier()\r
+ {\r
+ }\r
+ #endregion\r
+\r
+ /// <summary>\r
+ /// 拡大率の取得\r
+ /// </summary>\r
+ /// <param name="width_org">元の幅</param>\r
+ /// <param name="height_org">元の高さ</param>\r
+ /// <param name="magX_org">元の拡大率(幅)</param>\r
+ /// <param name="magY_org">元の拡大率(高さ)</param>\r
+ /// <param name="bIsPreview">選曲画面(preview)用か、演奏画面用か</param>\r
+ /// <remarks>出力はプロパティで得てください。</remarks>\r
+ public void GetMagnifier( int width_org, int height_org, float magX_org, float magY_org, bool bIsPreview)\r
+ {\r
+ this.bIsPreview = bIsPreview;\r
+\r
+ #region [ HD版DTXManiaのプレビュー画像は特別扱いする ]\r
+ if ( width_org == width_hd_set && height_org == height_hd_set ) // HD版DTXManiaのプレビュー画像は特別扱いする\r
+ {\r
+ this.width = width_org;\r
+ this.height = height_org;\r
+ this.magX = 1.5f * magX_org;\r
+ this.magY = 1.5f * magY_org;\r
+ return;\r
+ }\r
+ #endregion\r
+\r
+ #region [ width ]\r
+ if ( width_org <= width_vga_set ) // width <= 204 なら、拡大率だけ変更\r
+ {\r
+ this.width = width_org;\r
+ this.magX = magX_org * Scale.X;\r
+ }\r
+ else if ( width_fhd_limit > width_org && width_org > width_vga_set ) // width >= 320 なら原寸表示\r
+ {\r
+ this.width = width_vga_set;\r
+ this.magX = magX_org * Scale.X;\r
+ }\r
+ else if ( width_org >= width_fhd_limit )\r
+ {\r
+ this.width = (int) ( width_vga_set * Scale.X );\r
+ this.magX = magX_org; // / width_hd_set;\r
+ }\r
+ else\r
+ {\r
+ this.width = width_org;\r
+ this.magX = magX_org * Scale.X;\r
+ }\r
+ #endregion\r
+\r
+ #region [ height ]\r
+ if ( height_org <= height_vga_set ) // height <= 269 なら、拡大率だけ変更\r
+ {\r
+ this.height = height_org;\r
+ this.magY = magY_org * Scale.Y;\r
+ }\r
+ else if ( height_fhd_limit > height_org && height_org > height_vga_set ) // height >= 416 なら原寸表示\r
+ {\r
+ this.height = height_vga_set;\r
+ this.magY = magY_org * Scale.Y;\r
+ }\r
+ else if ( width_org >= height_fhd_limit )\r
+ {\r
+ this.height = (int) ( height_vga_set * Scale.Y );\r
+ this.magY = magY_org; // / height_fhd_set;\r
+ }\r
+ else\r
+ {\r
+ this.height = height_org;\r
+ this.magY = magY_org * Scale.Y;\r
+ }\r
+ #endregion\r
+ }\r
+\r
+ #region [ bIsPreviewによる配列→定数読み替え ]\r
+ private int width_vga_set\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview? WIDTH_VGA_SET[ 0 ] : WIDTH_VGA_SET[ 1 ];\r
+ }\r
+ }\r
+ private int height_vga_set\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview? HEIGHT_VGA_SET[ 0 ] : HEIGHT_VGA_SET[ 1 ];\r
+ }\r
+ }\r
+ private int width_hd_set\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview? WIDTH_HD_SET[ 0 ] : WIDTH_HD_SET[1];\r
+ }\r
+ }\r
+ private int height_hd_set\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview? HEIGHT_HD_SET[ 0 ] : HEIGHT_HD_SET[ 1 ];\r
+ }\r
+ }\r
+ private int width_fhd_limit\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview? WIDTH_FHD_LIMIT[ 0 ] : WIDTH_FHD_LIMIT[ 1 ];\r
+ }\r
+ }\r
+ private int height_fhd_limit\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview? HEIGHT_FHD_LIMIT[ 0 ] : HEIGHT_FHD_LIMIT[ 1 ];\r
+ }\r
+ }\r
+ private int width_fhd_set\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview ? WIDTH_FHD_SET[ 0 ] : WIDTH_FHD_SET[ 1 ];\r
+ }\r
+ }\r
+ private int height_fhd_set\r
+ {\r
+ get\r
+ {\r
+ return bIsPreview ? HEIGHT_FHD_SET[ 0 ] : HEIGHT_FHD_SET[ 1 ];\r
+ }\r
+ }\r
+ #endregion\r
+\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Runtime.InteropServices;\r
+using System.Text;\r
+using System.Drawing;\r
+using System.Drawing.Drawing2D;\r
+using System.Diagnostics;\r
+\r
+namespace DTXMania\r
+{\r
+ /// <summary>\r
+ /// 高速描画版のCPrivateFontクラス。\r
+ /// といっても、一度レンダリングした結果をキャッシュして使いまわしているだけ。\r
+ /// </summary>\r
+ public class CPrivateFastFont : CPrivateFont\r
+ {\r
+ /// <summary>\r
+ /// キャッシュ容量\r
+ /// </summary>\r
+ private const int MAXCACHESIZE = 128;\r
+\r
+ private struct FontCache\r
+ {\r
+ // public Font font;\r
+ public string drawstr;\r
+ public DrawMode drawmode;\r
+ public Color fontColor;\r
+ public Color edgeColor;\r
+ public Color gradationTopColor;\r
+ public Color gradationBottomColor;\r
+ public Bitmap bmp;\r
+ public Rectangle rectStrings;\r
+ public Point ptOrigin;\r
+ }\r
+ private List<FontCache> listFontCache;\r
+\r
+\r
+ #region [ コンストラクタ ]\r
+ public CPrivateFastFont( FontFamily fontfamily, int pt, FontStyle style )\r
+ {\r
+ Initialize( null, fontfamily, pt, style );\r
+ }\r
+ public CPrivateFastFont( FontFamily fontfamily, int pt )\r
+ {\r
+ Initialize( null, fontfamily, pt, FontStyle.Regular );\r
+ }\r
+ public CPrivateFastFont( string fontpath, int pt, FontStyle style )\r
+ {\r
+ Initialize( fontpath, null, pt, style );\r
+ }\r
+ public CPrivateFastFont( string fontpath, int pt )\r
+ {\r
+ Initialize( fontpath, null, pt, FontStyle.Regular );\r
+ }\r
+ public CPrivateFastFont()\r
+ {\r
+ throw new ArgumentException("CPrivateFastFont: 引数があるコンストラクタを使用してください。");\r
+ }\r
+ #endregion\r
+ #region [ コンストラクタから呼ばれる初期化処理 ]\r
+ protected new void Initialize( string fontpath, FontFamily fontfamily, int pt, FontStyle style )\r
+ {\r
+ this.bDispose完了済み_CPrivateFastFont = false;\r
+ this.listFontCache = new List<FontCache>();\r
+ base.Initialize( fontpath, fontfamily, pt, style );\r
+ }\r
+ #endregion\r
+\r
+\r
+ #region [ DrawPrivateFontのオーバーロード群 ]\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public new Bitmap DrawPrivateFont( string drawstr, Color fontColor )\r
+ {\r
+ return DrawPrivateFont( drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public new Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor )\r
+ {\r
+ return DrawPrivateFont( drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ //public new Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ //{\r
+ // return DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );\r
+ //}\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public new Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ {\r
+ return DrawPrivateFont( drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor );\r
+ }\r
+\r
+#if こちらは使わない // (Bitmapではなく、CTextureを返す版)\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public CTexture DrawPrivateFont( string drawstr, Color fontColor )\r
+ {\r
+ Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White );\r
+ return CDTXMania.tテクスチャの生成( bmp, false );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor )\r
+ {\r
+ Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White );\r
+ return CDTXMania.tテクスチャの生成( bmp, false );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ //public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ //{\r
+ // Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );\r
+ // return CDTXMania.tテクスチャの生成( bmp, false );\r
+ //}\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ {\r
+ Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor );\r
+ return CDTXMania.tテクスチャの生成( bmp, false );\r
+ }\r
+#endif\r
+ #endregion\r
+\r
+ protected new Bitmap DrawPrivateFont( string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradationBottomColor )\r
+ {\r
+ #region [ 以前レンダリングしたことのある文字列/フォントか? (キャッシュにヒットするか?) ]\r
+ int index = listFontCache.FindIndex(\r
+ delegate( FontCache fontcache )\r
+ {\r
+ return (\r
+ drawstr == fontcache.drawstr &&\r
+ drawmode == fontcache.drawmode &&\r
+ fontColor == fontcache.fontColor &&\r
+ edgeColor == fontcache.edgeColor &&\r
+ gradationTopColor == fontcache.gradationTopColor &&\r
+ gradationBottomColor == fontcache.gradationBottomColor\r
+ // _font == fontcache.font\r
+ );\r
+ }\r
+ );\r
+ #endregion\r
+ if ( index < 0 )\r
+ {\r
+ // キャッシュにヒットせず。\r
+ #region [ レンダリングして、キャッシュに登録 ]\r
+ FontCache fc = new FontCache();\r
+ fc.bmp = base.DrawPrivateFont( drawstr, drawmode, fontColor, edgeColor, gradationTopColor, gradationBottomColor );\r
+ fc.drawstr = drawstr;\r
+ fc.drawmode = drawmode;\r
+ fc.fontColor = fontColor;\r
+ fc.edgeColor = edgeColor;\r
+ fc.gradationTopColor = gradationTopColor;\r
+ fc.gradationBottomColor = gradationBottomColor;\r
+ fc.rectStrings = RectStrings;\r
+ fc.ptOrigin = PtOrigin;\r
+ listFontCache.Add( fc );\r
+ // Debug.WriteLine( drawstr + ": Cacheにヒットせず。(cachesize=" + listFontCache.Count + ")" );\r
+ #endregion\r
+ #region [ もしキャッシュがあふれたら、最も古いキャッシュを破棄する ]\r
+ if ( listFontCache.Count > MAXCACHESIZE )\r
+ {\r
+ // Debug.WriteLine( "Cache溢れ。" + listFontCache[ 0 ].drawstr + " を解放します。" );\r
+ if ( listFontCache[ 0 ].bmp != null )\r
+ {\r
+ listFontCache[ 0 ].bmp.Dispose();\r
+ }\r
+ listFontCache.RemoveAt( 0 );\r
+ }\r
+ #endregion\r
+\r
+ // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。\r
+ return (Bitmap)listFontCache[ listFontCache.Count - 1 ].bmp.Clone();\r
+ }\r
+ else\r
+ {\r
+ // Debug.WriteLine( drawstr + ": Cacheにヒット!! index=" + index );\r
+ #region [ キャッシュにヒット。レンダリングは行わず、キャッシュ内のデータを返して終了。]\r
+ RectStrings = listFontCache[ index ].rectStrings;\r
+ PtOrigin = listFontCache[ index ].ptOrigin;\r
+ // 呼び出し元のDispose()でキャッシュもDispose()されないように、Clone()で返す。\r
+ return (Bitmap) listFontCache[ index ].bmp.Clone();\r
+ #endregion\r
+ }\r
+ }\r
+\r
+ #region [ IDisposable 実装 ]\r
+ //-----------------\r
+ public new void Dispose()\r
+ {\r
+ if ( !this.bDispose完了済み_CPrivateFastFont )\r
+ {\r
+ if ( listFontCache != null )\r
+ {\r
+ //Debug.WriteLine( "Disposing CPrivateFastFont()" );\r
+ #region [ キャッシュしている画像を破棄する ]\r
+ foreach ( FontCache bc in listFontCache )\r
+\r
+ {\r
+ if ( bc.bmp != null )\r
+ {\r
+ bc.bmp.Dispose();\r
+ }\r
+ }\r
+ #endregion\r
+ listFontCache.Clear();\r
+ listFontCache = null;\r
+ }\r
+ this.bDispose完了済み_CPrivateFastFont = true;\r
+ }\r
+ base.Dispose();\r
+ }\r
+ //-----------------\r
+ #endregion\r
+\r
+ #region [ private ]\r
+ //-----------------\r
+ protected bool bDispose完了済み_CPrivateFastFont;\r
+ //-----------------\r
+ #endregion\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using System.IO;\r
+using System.Runtime.InteropServices;\r
+using System.Drawing;\r
+using System.Drawing.Drawing2D;\r
+using System.Diagnostics;\r
+using SlimDX;\r
+using FDK;\r
+\r
+namespace DTXMania\r
+{\r
+ /// <summary>\r
+ /// プライベートフォントでの描画を扱うクラス。\r
+ /// </summary>\r
+ /// <exception cref="FileNotFoundException">フォントファイルが見つからない時に例外発生</exception>\r
+ /// <exception cref="ArgumentException">スタイル指定不正時に例外発生</exception>\r
+ /// <remarks>\r
+ /// 簡単な使い方\r
+ /// CPrivateFont prvFont = new CPrivateFont( CSkin.Path( @"Graphics\fonts\mplus-1p-bold.ttf" ), 36 ); // プライベートフォント\r
+ /// とか\r
+ /// CPrivateFont prvFont = new CPrivateFont( new FontFamily("MS UI Gothic"), 36, FontStyle.Bold ); // システムフォント\r
+ /// とかした上で、\r
+ /// Bitmap bmp = prvFont.DrawPrivateFont( "ABCDE", Color.White, Color.Black ); // フォント色=白、縁の色=黒の例。縁の色は省略可能\r
+ /// とか\r
+ /// Bitmap bmp = prvFont.DrawPrivateFont( "ABCDE", Color.White, Color.Black, Color.Yellow, Color.OrangeRed ); // 上下グラデーション(Yellow→OrangeRed)\r
+ /// とかして、\r
+ /// CTexture ctBmp = CDTXMania.tテクスチャの生成( bmp, false );\r
+ /// ctBMP.t2D描画( ~~~ );\r
+ /// で表示してください。\r
+ /// \r
+ /// 注意点\r
+ /// 任意のフォントでのレンダリングは結構負荷が大きいので、なるべkなら描画フレーム毎にフォントを再レンダリングするようなことはせず、\r
+ /// 一旦レンダリングしたものを描画に使い回すようにしてください。\r
+ /// また、長い文字列を与えると、返されるBitmapも横長になります。この横長画像をそのままテクスチャとして使うと、\r
+ /// 古いPCで問題を発生させやすいです。これを回避するには、一旦Bitmapとして取得したのち、256pixや512pixで分割して\r
+ /// テクスチャに定義するようにしてください。\r
+ /// </remarks>\r
+ public class CPrivateFont : IDisposable\r
+ {\r
+ #region [ コンストラクタ ]\r
+ public CPrivateFont( FontFamily fontfamily, int pt, FontStyle style )\r
+ {\r
+ Initialize( null, fontfamily, pt, style );\r
+ }\r
+ public CPrivateFont( FontFamily fontfamily, int pt )\r
+ {\r
+ Initialize( null, fontfamily, pt, FontStyle.Regular );\r
+ }\r
+ public CPrivateFont( string fontpath, int pt, FontStyle style )\r
+ {\r
+ Initialize( fontpath, null, pt, style );\r
+ }\r
+ public CPrivateFont( string fontpath, int pt )\r
+ {\r
+ Initialize( fontpath, null, pt, FontStyle.Regular );\r
+ }\r
+ public CPrivateFont()\r
+ {\r
+ //throw new ArgumentException("CPrivateFont: 引数があるコンストラクタを使用してください。");\r
+ }\r
+ #endregion\r
+\r
+ protected void Initialize( string fontpath, FontFamily fontfamily, int pt, FontStyle style )\r
+ {\r
+ this._pfc = null;\r
+ this._fontfamily = null;\r
+ this._font = null;\r
+ this._pt = pt;\r
+ this._rectStrings = new Rectangle( 0, 0, 0, 0 );\r
+ this._ptOrigin = new Point( 0, 0 );\r
+ this.bDispose完了済み = false;\r
+\r
+ if ( fontfamily != null )\r
+ {\r
+ this._fontfamily = fontfamily;\r
+ }\r
+ else\r
+ {\r
+ try\r
+ {\r
+ this._pfc = new System.Drawing.Text.PrivateFontCollection(); //PrivateFontCollectionオブジェクトを作成する\r
+ this._pfc.AddFontFile( fontpath ); //PrivateFontCollectionにフォントを追加する\r
+ }\r
+ catch ( System.IO.FileNotFoundException )\r
+ {\r
+ Trace.TraceError( "プライベートフォントの追加に失敗しました。({0})", fontpath );\r
+ throw new FileNotFoundException( "プライベートフォントの追加に失敗しました。({0})", Path.GetFileName( fontpath ) );\r
+ //return;\r
+ }\r
+\r
+ //foreach ( FontFamily ff in pfc.Families )\r
+ //{\r
+ // Debug.WriteLine( "fontname=" + ff.Name );\r
+ // if ( ff.Name == Path.GetFileNameWithoutExtension( fontpath ) )\r
+ // {\r
+ // _fontfamily = ff;\r
+ // break;\r
+ // }\r
+ //}\r
+ //if ( _fontfamily == null )\r
+ //{\r
+ // Trace.TraceError( "プライベートフォントの追加後、検索に失敗しました。({0})", fontpath );\r
+ // return;\r
+ //}\r
+ _fontfamily = _pfc.Families[ 0 ];\r
+ }\r
+\r
+ // 指定されたフォントスタイルが適用できない場合は、フォント内で定義されているスタイルから候補を選んで使用する\r
+ // 何もスタイルが使えないようなフォントなら、例外を出す。\r
+ if ( !_fontfamily.IsStyleAvailable( style ) )\r
+ {\r
+ FontStyle[] FS = { FontStyle.Regular, FontStyle.Bold, FontStyle.Italic, FontStyle.Underline, FontStyle.Strikeout };\r
+ style = FontStyle.Regular | FontStyle.Bold | FontStyle.Italic | FontStyle.Underline | FontStyle.Strikeout; // null非許容型なので、代わりに全盛をNGワードに設定\r
+ foreach ( FontStyle ff in FS )\r
+ {\r
+ if ( this._fontfamily.IsStyleAvailable( ff ) )\r
+ {\r
+ style = ff;\r
+ Trace.TraceWarning( "フォント{0}へのスタイル指定を、{1}に変更しました。", Path.GetFileName( fontpath ), style.ToString() );\r
+ break;\r
+ }\r
+ }\r
+ if ( style == ( FontStyle.Regular | FontStyle.Bold | FontStyle.Italic | FontStyle.Underline | FontStyle.Strikeout ) )\r
+ {\r
+ throw new ArgumentException( "フォント{0}は適切なスタイルを選択できず、使用できません。", Path.GetFileName( fontpath ) );\r
+ }\r
+ }\r
+ this._font = new Font( this._fontfamily, pt, style ); //PrivateFontCollectionの先頭のフォントのFontオブジェクトを作成する\r
+ }\r
+\r
+ [Flags]\r
+ protected enum DrawMode\r
+ {\r
+ Normal,\r
+ Edge,\r
+ Gradation\r
+ }\r
+\r
+ #region [ DrawPrivateFontのオーバーロード群 ]\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public Bitmap DrawPrivateFont( string drawstr, Color fontColor )\r
+ {\r
+ return DrawPrivateFont( drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor )\r
+ {\r
+ return DrawPrivateFont( drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ //public Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ //{\r
+ // return DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );\r
+ //}\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public Bitmap DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ {\r
+ return DrawPrivateFont( drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor );\r
+ }\r
+\r
+#if こちらは使わない // (Bitmapではなく、CTextureを返す版)\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public CTexture DrawPrivateFont( string drawstr, Color fontColor )\r
+ {\r
+ Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Normal, fontColor, Color.White, Color.White, Color.White );\r
+ return CDTXMania.tテクスチャの生成( bmp, false );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor )\r
+ {\r
+ Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge, fontColor, edgeColor, Color.White, Color.White );\r
+ return CDTXMania.tテクスチャの生成( bmp, false );\r
+ }\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ //public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ //{\r
+ // Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Gradation, fontColor, Color.White, gradationTopColor, gradataionBottomColor );\r
+ // return CDTXMania.tテクスチャの生成( bmp, false );\r
+ //}\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す\r
+ /// </summary>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ public CTexture DrawPrivateFont( string drawstr, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradataionBottomColor )\r
+ {\r
+ Bitmap bmp = DrawPrivateFont( drawstr, DrawMode.Edge | DrawMode.Gradation, fontColor, edgeColor, gradationTopColor, gradataionBottomColor );\r
+ return CDTXMania.tテクスチャの生成( bmp, false );\r
+ }\r
+#endif\r
+ #endregion\r
+\r
+\r
+ /// <summary>\r
+ /// 文字列を描画したテクスチャを返す(メイン処理)\r
+ /// </summary>\r
+ /// <param name="rectDrawn">描画された領域</param>\r
+ /// <param name="ptOrigin">描画文字列</param>\r
+ /// <param name="drawstr">描画文字列</param>\r
+ /// <param name="drawmode">描画モード</param>\r
+ /// <param name="fontColor">描画色</param>\r
+ /// <param name="edgeColor">縁取色</param>\r
+ /// <param name="gradationTopColor">グラデーション 上側の色</param>\r
+ /// <param name="gradationBottomColor">グラデーション 下側の色</param>\r
+ /// <returns>描画済テクスチャ</returns>\r
+ protected Bitmap DrawPrivateFont( string drawstr, DrawMode drawmode, Color fontColor, Color edgeColor, Color gradationTopColor, Color gradationBottomColor )\r
+ {\r
+ if ( this._fontfamily == null || drawstr == null || drawstr == "" )\r
+ {\r
+ // nullを返すと、その後bmp→texture処理や、textureのサイズを見て・・の処理で全部例外が発生することになる。\r
+ // それは非常に面倒なので、最小限のbitmapを返してしまう。\r
+ // まずはこの仕様で進めますが、問題有れば(上位側からエラー検出が必要であれば)例外を出したりエラー状態であるプロパティを定義するなり検討します。\r
+ if ( drawstr != "" )\r
+ {\r
+ Trace.TraceWarning( "DrawPrivateFont()の入力不正。最小値のbitmapを返します。" );\r
+ }\r
+ _rectStrings = new Rectangle( 0, 0, 0, 0 );\r
+ _ptOrigin = new Point( 0, 0 );\r
+ return new Bitmap(1, 1);\r
+ }\r
+ bool bEdge = ( ( drawmode & DrawMode.Edge ) == DrawMode.Edge );\r
+ bool bGradation = ( ( drawmode & DrawMode.Gradation ) == DrawMode.Gradation );\r
+\r
+ // 縁取りの縁のサイズは、とりあえずフォントの大きさの1/4とする\r
+ int nEdgePt = (bEdge)? _pt / 4 : 0;\r
+\r
+ // 描画サイズを測定する\r
+ Size stringSize = System.Windows.Forms.TextRenderer.MeasureText( drawstr, this._font );\r
+\r
+ //取得した描画サイズを基に、描画先のbitmapを作成する\r
+ Bitmap bmp = new Bitmap( stringSize.Width + nEdgePt * 2, stringSize.Height + nEdgePt * 2 );\r
+ bmp.MakeTransparent();\r
+ Graphics g = Graphics.FromImage( bmp );\r
+ g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;\r
+\r
+ StringFormat sf = new StringFormat();\r
+ sf.LineAlignment = StringAlignment.Far; // 画面下部(垂直方向位置)\r
+ sf.Alignment = StringAlignment.Center; // 画面中央(水平方向位置)\r
+\r
+ // レイアウト枠\r
+ Rectangle r = new Rectangle( 0, 0, stringSize.Width + nEdgePt * 2, stringSize.Height + nEdgePt * 2 );\r
+\r
+ if ( bEdge ) // 縁取り有りの描画\r
+ {\r
+ // DrawPathで、ポイントサイズを使って描画するために、DPIを使って単位変換する\r
+ // (これをしないと、単位が違うために、小さめに描画されてしまう)\r
+ float sizeInPixels = _font.SizeInPoints * g.DpiY / 72; // 1 inch = 72 points\r
+\r
+ System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();\r
+ gp.AddString( drawstr, this._fontfamily, (int) this._font.Style, sizeInPixels, r, sf );\r
+\r
+ // 縁取りを描画する\r
+ Pen p = new Pen( edgeColor, nEdgePt );\r
+ p.LineJoin = System.Drawing.Drawing2D.LineJoin.Round;\r
+ g.DrawPath( p, gp );\r
+\r
+ // 塗りつぶす\r
+ Brush br;\r
+ if ( bGradation )\r
+ {\r
+ br = new LinearGradientBrush( r, gradationTopColor, gradationBottomColor, LinearGradientMode.Vertical );\r
+ }\r
+ else\r
+ {\r
+ br = new SolidBrush( fontColor );\r
+ }\r
+ g.FillPath( br, gp );\r
+\r
+ if ( br != null ) br.Dispose(); br = null;\r
+ if ( p != null ) p.Dispose(); p = null;\r
+ if ( gp != null ) gp.Dispose(); gp = null;\r
+ }\r
+ else\r
+ {\r
+ // 縁取りなしの描画\r
+ System.Windows.Forms.TextRenderer.DrawText( g, drawstr, _font, new Point( 0, 0 ), fontColor );\r
+ }\r
+#if debug表示\r
+ g.DrawRectangle( new Pen( Color.White, 1 ), new Rectangle( 1, 1, stringSize.Width-1, stringSize.Height-1 ) );\r
+ g.DrawRectangle( new Pen( Color.Green, 1 ), new Rectangle( 0, 0, bmp.Width - 1, bmp.Height - 1 ) );\r
+#endif\r
+ _rectStrings = new Rectangle( 0, 0, stringSize.Width, stringSize.Height );\r
+ _ptOrigin = new Point( nEdgePt * 2, nEdgePt * 2 );\r
+ \r
+\r
+ #region [ リソースを解放する ]\r
+ if ( sf != null ) sf.Dispose(); sf = null;\r
+ if ( g != null ) g.Dispose(); g = null;\r
+ #endregion\r
+\r
+ return bmp;\r
+ }\r
+\r
+ /// <summary>\r
+ /// 最後にDrawPrivateFont()した文字列の描画領域を取得します。\r
+ /// </summary>\r
+ public Rectangle RectStrings\r
+ {\r
+ get\r
+ {\r
+ return _rectStrings;\r
+ }\r
+ protected set\r
+ {\r
+ _rectStrings = value;\r
+ }\r
+ }\r
+ public Point PtOrigin\r
+ {\r
+ get\r
+ {\r
+ return _ptOrigin;\r
+ }\r
+ protected set\r
+ {\r
+ _ptOrigin = value;\r
+ }\r
+ }\r
+\r
+ #region [ IDisposable 実装 ]\r
+ //-----------------\r
+ public void Dispose()\r
+ {\r
+ if ( !this.bDispose完了済み )\r
+ {\r
+ if ( this._font != null )\r
+ {\r
+ this._font.Dispose();\r
+ this._font = null;\r
+ }\r
+ if ( this._pfc != null )\r
+ {\r
+ this._pfc.Dispose();\r
+ this._pfc = null;\r
+ }\r
+\r
+ this.bDispose完了済み = true;\r
+ }\r
+ }\r
+ //-----------------\r
+ #endregion\r
+\r
+ #region [ private ]\r
+ //-----------------\r
+ protected bool bDispose完了済み;\r
+ protected Font _font;\r
+\r
+ private System.Drawing.Text.PrivateFontCollection _pfc;\r
+ private FontFamily _fontfamily;\r
+ private int _pt;\r
+ private Rectangle _rectStrings;\r
+ private Point _ptOrigin;\r
+ //-----------------\r
+ #endregion\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+\r
+namespace DTXMania\r
+{\r
+ /// <summary>\r
+ /// VGA座標系をFullHD座標系に変換するための、当座のしのぎ。\r
+ /// </summary>\r
+ public struct Scale\r
+ {\r
+ public const float X = SampleFramework.GameWindowSize.Width / 640f;\r
+ public const float Y = SampleFramework.GameWindowSize.Height / 480f;\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Runtime.InteropServices;\r
+using System.Diagnostics;\r
+using System.Text;\r
+\r
+namespace FDK\r
+{\r
+ public static class CSendMessage\r
+ {\r
+\r
+ [DllImport( "USER32.dll" )]\r
+ static extern uint SendMessage( IntPtr window, int msg, IntPtr wParam, ref SampleFramework.COPYDATASTRUCT lParam );\r
+ \r
+ \r
+ public static uint sendmessage( IntPtr MainWindowHandle, IntPtr FromWindowHandle, string arg)\r
+ {\r
+ uint len = (uint) arg.Length;\r
+\r
+ SampleFramework.COPYDATASTRUCT cds;\r
+ cds.dwData = IntPtr.Zero; // 使用しない\r
+ cds.lpData = Marshal.StringToHGlobalUni( arg ); // テキストのポインターをセット\r
+ cds.cbData = ( len + 1 ) * 2; // 長さをセット\r
+\r
+ //文字列を送る\r
+ uint result = SendMessage( MainWindowHandle, SampleFramework.WindowConstants.WM_COPYDATA, FromWindowHandle, ref cds );\r
+\r
+ Marshal.FreeHGlobal( cds.lpData );\r
+\r
+ return result;\r
+ }\r
+ }\r
+}\r
{\r
public static class GameWindowSize\r
{\r
- public const int Width = 640;\r
- public const int Height = 480;\r
+ public const int Width = 1920;\r
+ public const int Height = 1080;\r
}\r
}\r