}
private const double _最小区切り時間 = 2.0; // 区切り線を入れる最小の間隔[秒]。
+
private static string _日時とスレッドID
{
get
return $"{DateTime.Now.ToLongTimeString()} [{NETスレッドID:00},0x{Win32スレッドID:x}{スレッド識別文字列}]";
}
}
+
private static readonly Dictionary<uint, string> _IDto名前 = new Dictionary<uint, string>();
+
private static Dictionary<string, DateTime> _識別キー別最終表示時刻 = new Dictionary<string, DateTime>();
+
private static TimeSpan _経過時間
{
get
return 経過時間;
}
}
+
private static DateTime _最終表示時刻 = DateTime.Now;
+
private static int _深さ = 0;
+
private static readonly object _スレッド間同期 = new object();
private static void _一定時間が経過していたら区切り線を表示する()
if( Log._最小区切り時間 < Log._経過時間.TotalSeconds )
Trace.TraceInformation( "・・・" );
}
+
private static string _インデックスを返す( int 長さ )
{
string index = " ";
}
private int _現在のFPS = 0;
+
private int _現在のVPS = 0;
+
private int _fps用カウンタ = 0;
+
private int _vps用カウンタ = 0;
+
private FDK.カウンタ.定間隔進行 _定間隔進行 = null;
+
private bool _初めてのFPS更新 = true;
+
private readonly object _スレッド間同期 = new object();
}
}
}
private long _前回リセットした時点の生カウント = 0;
+
private long _最後にキャプチャされたカウント = 0;
+
private long _稼働中に一時停止した時点のキャプチャカウント = 0;
+
private int _一時停止回数 = 0;
+
private readonly object _スレッド間同期 = new object();
}
}
}
private int _開始値 = 0;
+
private int _終了値 = 0;
+
private int _現在値 = 0;
+
private bool _動作中 = false;
+
private long _間隔ms = QPCTimer.未使用;
+
private 定間隔進行 _定間隔進行 = null;
+
private readonly object _スレッド間同期 = new object();
/// <summary>
}
private int _開始値 = 0;
+
private int _終了値 = 0;
+
private int _現在値 = 0;
+
private bool _動作中 = false;
+
private long _間隔ms = QPCTimer.未使用;
+
private 定間隔進行 _定間隔進行 = null;
+
private readonly object _スレッド間同期 = new object();
/// <summary>
}
private long _前回の進行時刻ms = QPCTimer.未使用;
+
private readonly QPCTimer _タイマ = new QPCTimer();
+
private readonly object _スレッド間同期 = new object();
}
}
}
private CSCore.MediaFoundation.MFMediaType _MediaType = null;
+
private byte[] _EncodedWaveData = null;
+
private long _Position = 0;
private void _初期化する( string path )
{
try
{
- // SharpDX ではなく CSCore を使う。(MediaType から WaveFormat に一発で変換できるので。)
+ // SourceReader は、SharpDX ではなく CSCore のものを使う。(MediaType から WaveFormat に一発で変換できるので。)
using( var sourceReader = new CSCore.MediaFoundation.MFSourceReader( path ) )
using( var waveStream = new System.IO.MemoryStream() )
{
// 完成されたメディアタイプを取得する。
this._MediaType = sourceReader.GetCurrentMediaType( (int) SharpDX.MediaFoundation.SourceReaderIndex.FirstAudioStream );
- // ã\83¡ã\83\87ã\82£ã\82¢ã\82¿ã\82¤ã\83\97ã\81\8bã\82\89ã\83\95ã\82©ã\83¼ã\83\9eã\83\83ã\83\88ã\82\92å\8f\96å¾\97ã\81\99ã\82\8bã\80\82ï¼\88å\90\8cã\81\98ã\81®はずだが念のため)
+ // ã\83¡ã\83\87ã\82£ã\82¢ã\82¿ã\82¤ã\83\97ã\81\8bã\82\89ã\83\95ã\82©ã\83¼ã\83\9eã\83\83ã\83\88ã\82\92å\8f\96å¾\97ã\81\99ã\82\8bã\80\82ï¼\88å\90\8cã\81\98ã\81§ã\81\82ã\82\8bはずだが念のため)
this.WaveFormat = this._MediaType.ToWaveFormat( CSCore.MediaFoundation.MFWaveFormatExConvertFlags.Normal );
// 最初のオーディオストリームが選択されていることを保証する。
}
catch( Exception e )
{
- FDK.Log.ERROR( $"WASAPI.Decoder の初期化に失敗しました。[{e.Message}]" );
+ FDK.Log.ERROR( $"MediaFoundation SourceReader の初期化に失敗しました。[{e.Message}]" );
this._EncodedWaveData = new byte[] { };
}
}
}
- #region " 解放; Dispose-Finallize パターン "
+ #region " 解放; Dispose-Finalize パターン "
//----------------
~Device()
{
//----------------
#endregion
-
private volatile CSCore.SoundOut.PlaybackState _レンダリング状態 = CSCore.SoundOut.PlaybackState.Stopped;
private CSCore.CoreAudioAPI.AudioClientShareMode _共有モード;
private bool _dispose済み = false;
-
private void _初期化する( CSCore.WaveFormat 希望フォーマット )
{
lock( this._スレッド間同期 )
// MMDevice を取得する。
this._MMDevice = CSCore.CoreAudioAPI.MMDeviceEnumerator.DefaultAudioEndpoint(
- CSCore.CoreAudioAPI.DataFlow.Render, // 方向:再生
+ CSCore.CoreAudioAPI.DataFlow.Render, // 方向:書き込み
CSCore.CoreAudioAPI.Role.Console ); // 用途:ゲーム、システム通知音、音声命令
// AudioClient を取得する。
}
}
- // イベント駆動用に使うイベントを生成し、AudioClient へ登録する。
+ // イベント駆動に使うイベントを生成し、AudioClient へ登録する。
this._レンダリングイベント = new System.Threading.EventWaitHandle( false, System.Threading.EventResetMode.AutoReset );
this._AudioClient.SetEventHandle( this._レンダリングイベント.SafeWaitHandle.DangerousGetHandle() );
}
else if( null != 最も近いフォーマット )
{
- // (B) AudioClient ã\81\8cæ\8e¨å¥¨ã\83\95ã\82©ã\83¼ã\83\9eã\83\83ã\83\88ã\82\92è¿\94ã\81\97ã\81¦ã\81\8dã\81\9fã\81ªã\82\89、それを採択する。
+ // (B) AudioClient ã\81\8cæ\8e¨å¥¨ã\83\95ã\82©ã\83¼ã\83\9eã\83\83ã\83\88ã\82\92è¿\94ã\81\97ã\81¦ã\81\8dã\81\9fã\81®ã\81§、それを採択する。
最終的に決定されたフォーマット = 最も近いフォーマット;
}
else
{
- // (C) AudioClient からの提案がなかった場合は、共有モードのフォーマットを採択する。
+ // (C) AudioClient からの提案がなかったので、共有モードのフォーマットを採択してみる。
var 共有モードのフォーマット = this._AudioClient.GetMixFormat();
}
else
{
- // (D) AudioClient が共有モードのフォーマットもNGである場合は、以下から探す。
+ // (D) 共有モードのフォーマットも NG である場合は、以下から探す。
CSCore.WaveFormat closest = null;
/*
* 24bit PCM には対応しない。
*
+ * https://msdn.microsoft.com/ja-jp/library/cc371566.aspx
* > wFormatTag が WAVE_FORMAT_PCM の場合、wBitsPerSample は 8 または 16 でなければならない。
* > wFormatTag が WAVE_FORMAT_EXTENSIBLE の場合、この値は、任意の 8 の倍数を指定できる。
- * https://msdn.microsoft.com/ja-jp/library/cc371566.aspx
*
* また、Realtek HD Audio の場合、IAudioClient.IsSupportedFormat() は 24bit PCM でも true を返してくるが、
* 単純に 1sample = 3byte で書き込んでも正常に再生できない。
}
.FirstOrDefault( ( format ) => ( this._AudioClient.IsFormatSupported( this._共有モード, format ) ) );
- // (E) それでも見つからなかったら null 。
+ // (E) ã\81\9dã\82\8cã\81§ã\82\82è¦\8bã\81¤ã\81\8bã\82\89ã\81ªã\81\8bã\81£ã\81\9fã\82\89 null ã\81®ã\81¾ã\81¾ã\80\82
}
}
{
int イベント番号 = System.Threading.WaitHandle.WaitAny(
waitHandles: イベントs,
- millisecondsTimeout: (int) ( 3000.0 * this.遅延sec ), // 適正値は レイテンシ×3 [ms] (MSDN)
+ millisecondsTimeout: (int) ( 3000.0 * this.遅延sec ), // 適正値は レイテンシ×3 [ms] (MSDNより)
exitContext: false );
if( イベント番号 == System.Threading.WaitHandle.WaitTimeout )
if( 0 < 読み込むサイズsample )
{
- // ミキサーからの出力をバッファに取得する。
+ // ミキサーからの出力(32bit-float)をバッファに取得する。
int 読み込んだサイズsample = this._Mixer.Read( バッファ, 0, 読み込むサイズsample );
// バッファのデータを変換しつつ、AudioRenderClient へ出力する。
{
if( 24 == this.WaveFormat.BitsPerSample )
{
- #region " (A) Mixer:32bit-float → AudioRenderClient:24bit-PCM の場合 "
+ #region " (A) (Mixer)32bit-float → (AudioRenderClient)24bit-PCM の場合 "
//----------------
+ // 以下のコードでは、まだ、まともに再生できない。おそらくザーッという大きいノイズだらけの音になる。
unsafe
{
byte* ptr = (byte*) bufferPtr.ToPointer(); // AudioRenderClient のバッファは GC 対象外なのでピン止め不要。
}
else if( 16 == this.WaveFormat.BitsPerSample )
{
- #region " (B) Mixer:32bit-float → AudioRenderClient:16bit-PCM の場合 "
+ #region " (B) (Mixer)32bit-float → (AudioRenderClient)16bit-PCM の場合 "
//----------------
unsafe
{
}
else if( 8 == this.WaveFormat.BitsPerSample )
{
- #region " (C) Mixer:32bit-float → AudioRenderClient:8bit-PCM の場合 "
+ #region " (C) (Mixer)32bit-float → (AudioRenderClient)8bit-PCM の場合 "
//----------------
unsafe
{
}
else if( encoding == AudioEncoding.IeeeFloat )
{
- #region " (D) Mixer:32bit-float → AudioRenderClient:32bit-float の場合 "
+ #region " (D) (Mixer)32bit-float → (AudioRenderClient)32bit-float の場合 "
//----------------
Marshal.Copy( バッファ, 0, bufferPtr, 読み込んだサイズsample );
//----------------
internal class Mixer : CSCore.ISampleSource
{
/// <summary>
- /// 音量。0.0(無音)~1.0(原音)。
+ /// 音量。0.0(無音)~1.0(原音)。
/// </summary>
public float Volume
{
this._WaveFormat = deviceWaveFormat;
}
+ /// <summary>
+ /// ミキサに登録されているサウンドをすべて停止し解放する。
+ /// </summary>
public void Dispose()
{
lock( this._スレッド間同期 )
if( null == sound )
throw new ArgumentNullException();
- if( ( sound.SampleSource.WaveFormat.Channels != this._WaveFormat.Channels ) ||
- ( sound.SampleSource.WaveFormat.SampleRate != this._WaveFormat.SampleRate ) ||
- ( sound.SampleSource.WaveFormat.WaveFormatTag != AudioEncoding.IeeeFloat ) ) // IWaveSource.ToSampleSource() で作成した ISampleSource ならすべて 32bit-float であるはず。
+ if( ( sound.SampleSource.WaveFormat.Channels != this._WaveFormat.Channels ) || // 同じチャンネル数、
+ ( sound.SampleSource.WaveFormat.SampleRate != this._WaveFormat.SampleRate ) || // 同じ周波数、
+ ( sound.SampleSource.WaveFormat.WaveFormatTag != AudioEncoding.IeeeFloat ) ) // 常に 32bit-float であること。
{
- // これらの変換は面倒なのでサポートしない。
+ // 違った場合の変換はサポートしない。
throw new ArgumentException( "ミキサーと同じチャンネル数、サンプルレート、かつ 32bit float 型である必要があります。" );
}
/// <summary>
/// Sound がミキサーに登録されているかを調べる。
/// </summary>
- /// <returns>Sound がミキサーに追加済みなら true 。</returns>
+ /// <returns>
+ /// Sound がミキサーに追加済みなら true 。
+ /// </returns>
public bool Contains( Sound sound )
{
if( null == sound )
/// <summary>
/// バッファにサウンドデータを出力する。
/// </summary>
- /// <returns>実際に出力したサンプル数。</returns>
+ /// <returns>
+ /// 実際に出力したサンプル数。
+ /// </returns>
public int Read( float[] バッファ, int バッファの出力開始位置, int 出力サンプル数 )
{
// ミキサに登録されている Sound の入力とこのメソッドが出力するデータはいずれも常に 32bit-float であり、
lock( this._スレッド間同期 )
{
// 中間バッファが十分あることを確認する。足りなければ新しく確保して戻ってくる。
- this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡ = this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡.CheckBuffer( å\87ºå\8a\9bã\82µã\83³ã\83\97ã\83«æ\95° ); // ã\82µã\83³ã\83\97ã\83«æ\95°ã\81§ã\81\82ã\81£ã\81¦、フレーム数(サンプル数×チャンネル数)ではない。
+ this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡ = this._ä¸é\96\93ã\83\90ã\83\83ã\83\95ã\82¡.CheckBuffer( å\87ºå\8a\9bã\82µã\83³ã\83\97ã\83«æ\95° ); // ã\82µã\83³ã\83\97ã\83«æ\95°ã\81§ã\81\82ã\82\8a、フレーム数(サンプル数×チャンネル数)ではない。
- // 無音を出力する。
+ // まずは無音で埋める。
Array.Clear( バッファ, 0, 出力サンプル数 );
- // ã\83\9fã\82ã\82µã\81«ç\99»é\8c²ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\81\99ã\81¹ã\81¦ã\81® Sound ã\82\92å\87ºå\8a\9bする。
+ // ã\81\9dã\81®ä¸\8aã\81«ã\80\81ã\83\9fã\82ã\82µã\81«ç\99»é\8c²ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\81\99ã\81¹ã\81¦ã\81® Sound ã\82\92å\8a ç®\97å\90\88æ\88\90する。
if( 0 < this._Sounds.Count )
{
for( int m = this._Sounds.Count - 1; m >= 0; m-- ) // リストから Remove する場合があるので、リストの後ろから進める。
// 中間バッファにサウンドデータを受け取る。
int 受け取ったサンプル数 = sound.SampleSource.Read( this._中間バッファ, 0, 出力サンプル数 );
- // 中間バッファから出力バッファへ転送する。
+ // 中間バッファから出力バッファへ合成する。
for( int i = バッファの出力開始位置, n = 0; n < 受け取ったサンプル数; i++, n++ )
{
float data = this._中間バッファ[ n ] // 原音
- * sound.Volume // 個別音量
- * this._Volume; // ã\83\9fã\82ã\82µé\9f³é\87\8f
+ * sound.Volume // 個別音量(Sound)
+ * this._Volume; // ã\83\9eã\82¹ã\82¿é\9f³é\87\8fï¼\88ã\83\9fã\82ã\82µï¼\89
- // ベースに無音を出力済みなので、上書きじゃなく常に加算。
+ // 先に無音を出力済みなので、上書きかどうかを気にしないで常に加算。
バッファ[ i ] += data;
}
}
private float _Volume = 1.0f;
+
private CSCore.WaveFormat _WaveFormat = null;
+
private readonly List<Sound> _Sounds = new List<Sound>();
+
private float[] _中間バッファ = null;
+
private readonly object _スレッド間同期 = new object();
}
}
{
get { return this._SampleSource.Length; }
}
+
public double 長さsec
{
get { return this._SampleToSec( this.長さsample ); }
get { return this._SampleSource.Position; }
set { this._SampleSource.Position = value; }
}
+
public double 位置sec
{
get
get;
protected set;
} = false;
+
public bool 再生停止中である
{
get { return !this.再生中である; }
{
get { return this._SampleSource; }
}
+
public CSCore.IWaveSource WaveSource
{
get { return this._WaveSource; }
}
/// <summary>
- /// Sound の生成は、コンストラクタではなく Device.CreateSound() で行うこと。
- /// (Device 内部で持っている Mixer への参照が必要なため。)
+ /// Sound の生成は、コンストラクタではなく Device.CreateSound() で行うこと。
+ /// (Device 内部で持っている Mixer への参照が必要なため。)
/// </summary>
- /// <param name="path">サウンドファイルパス</param>
- /// <param name="mixer">使用する Mixer。</param>
+ /// <param name="path">
+ /// サウンドファイルパス
+ /// </param>
+ /// <param name="mixer">
+ /// 使用する Mixer。
+ /// </param>
internal Sound( string path, Mixer mixer )
{
this._MixerRef = new WeakReference<Mixer>( mixer );
this._WaveSource = new DecodedWaveSource( path, mixer.WaveFormat );
this._SampleSource = this._WaveSource.ToSampleSource();
}
+
+ /// <summary>
+ /// Sound の生成は、コンストラクタではなく Device.CreateSound() で行うこと。
+ /// (Device 内部で持っている Mixer への参照が必要なため。)
+ /// </summary>
+ /// <param name="source">
+ /// サウンドの IWaveSource インスタンス。
+ /// </param>
+ /// <param name="mixer">
+ /// 使用する Mixer。
+ /// </param>
internal Sound( IWaveSource source, Mixer mixer )
{
this._MixerRef = new WeakReference<Mixer>( mixer );
this._SampleSource = this._WaveSource.ToSampleSource();
}
+ /// <summary>
+ /// サウンドデータを解放する。
+ /// </summary>
public void Dispose()
{
this.Stop();
this._MixerRef = null;
}
+ /// <summary>
+ /// 再生を開始する。
+ /// </summary>
+ /// <param name="再生開始位置sample">
+ /// 再生開始位置。サンプル単位。(フレーム単位じゃない。)
+ /// </param>
public void Play( long 再生開始位置sample = 0 )
{
this.位置sample = 再生開始位置sample;
}
}
+ /// <summary>
+ /// 再生を開始する。
+ /// </summary>
+ /// <param name="再生開始位置sec">
+ /// 再生開始位置。秒単位。
+ /// </param>
public void Play( double 再生開始位置sec )
{
this.Play( this._SecToSample( 再生開始位置sec ) );
}
+ /// <summary>
+ /// 再生を停止する。
+ /// </summary>
public void Stop()
{
Mixer mixer;
}
private CSCore.IWaveSource _WaveSource = null;
+
private CSCore.ISampleSource _SampleSource = null;
+
private System.WeakReference<Mixer> _MixerRef = null;
+
private float _Volume = 1.0f;
private long _SecToSample( double 時間sec )
}
protected SharpDX.Size2 ユーザ指定サイズdpx;
+
protected SharpDX.Direct3D11.Texture2D Texture = null;
private string _画像ファイルパス = null;
+
private SharpDX.Direct3D11.Buffer _ConstantBuffer = null;
+
private SharpDX.Direct3D11.ShaderResourceView _ShaderResourceView = null;
+
private SharpDX.Size2F _ShaderResourceViewSize;
+
private SharpDX.Direct3D11.BindFlags _bindFlags;
+
private struct ST定数バッファの転送元データ
{
public SharpDX.Matrix World; // ワールド変換行列
public float dummy2; // float4境界に合わせるためのダミー
public float dummy3; // float4境界に合わせるためのダミー
};
+
private ST定数バッファの転送元データ _定数バッファの転送元データ;
+
// (2) 全インスタンス共通項目(static)
public static void 全インスタンスで共有するリソースを作成する( FDK.メディア.デバイスリソース dr )
}
private static SharpDX.Direct3D11.VertexShader _VertexShader = null;
+
private static SharpDX.Direct3D11.PixelShader _PixelShader = null;
+
private static SharpDX.Direct3D11.BlendState _BlendState通常合成 = null;
+
private static SharpDX.Direct3D11.BlendState _BlendState加算合成 = null;
+
private static SharpDX.Direct3D11.RasterizerState _RasterizerState = null;
+
private static SharpDX.Direct3D11.SamplerState _SamplerState = null;
}
}
}
private FDK.メディア.テクスチャ _文字盤 = null;
+
private FDK.メディア.矩形リスト _文字矩形リスト = null;
}
}
{
get
{
- var カメラの位置 = new SharpDX.Vector3( 0f, 0f, ( -2f * this.dz( this.設計画面サイズdpx.Height, this.視野角deg ) ) );
+ var カメラの位置 = new SharpDX.Vector3( 0f, 0f, ( -2f * this._dz( this.設計画面サイズdpx.Height, this.視野角deg ) ) );
var カメラの注視点 = new SharpDX.Vector3( 0f, 0f, 0f );
var カメラの上方向 = new SharpDX.Vector3( 0f, 1f, 0f );
var mat = SharpDX.Matrix.LookAtLH( カメラの位置, カメラの注視点, カメラの上方向 );
{
get
{
- float dz = this.dz( this.設計画面サイズdpx.Height, this.視野角deg );
+ float dz = this._dz( this.設計画面サイズdpx.Height, this.視野角deg );
var mat = SharpDX.Matrix.PerspectiveFovLH(
SharpDX.MathUtil.DegreesToRadians( 視野角deg ),
設計画面サイズdpx.Width / 設計画面サイズdpx.Height, // アスペクト比
}
private SharpDX.Direct2D1.Factory2 _D2DFactory2 = null;
+
private SharpDX.DirectWrite.Factory _DWriteFactory = null;
+
private SharpDX.WIC.ImagingFactory2 _WicImagingFactory2 = null;
+
private SharpDX.MediaFoundation.DXGIDeviceManager _DXGIDeviceManager = null;
+
private SharpDX.DXGI.SwapChain1 _SwapChain1 = null;
+
private SharpDX.Mathematics.Interop.RawViewportF[] _D3DViewPort = new SharpDX.Mathematics.Interop.RawViewportF[ 1 ];
+
private SharpDX.Direct3D11.DepthStencilState _D3DDepthStencilState = null;
+
private SharpDX.Direct3D11.RenderTargetView _D3DRenderTargetView = null;
+
private SharpDX.Direct3D11.Texture2D _D3DDepthStencil = null;
+
private SharpDX.Direct3D11.DepthStencilView _D3DDepthStencilView = null;
+
private SharpDX.Direct3D11.DeviceDebug _D3DDeviceDebug = null;
+
private SharpDX.Direct2D1.Device1 _D2DDevice1 = null;
+
private SharpDX.Direct2D1.DeviceContext1 _D2DContext1 = null;
+
private SharpDX.Direct2D1.Bitmap1 _D2DRenderTargetBitmap = null;
- private float dz( float 高さdpx, float 視野角deg )
+ private float _dz( float 高さdpx, float 視野角deg )
{
return (float) ( 高さdpx / ( 4.0 * Math.Tan( SharpDX.MathUtil.DegreesToRadians( 視野角deg / 2.0f ) ) ) );
}
}
private int _キューのサイズ = 0;
+
private class FrameQueueItem : IDisposable
{
public double 表示時刻sec = 0;
FDK.Utilities.解放する( ref this.D2DBitmap );
}
}
+
private ConcurrentQueue<FrameQueueItem> _フレームキュー = null;
+
private FrameQueueItem _最後に表示したフレーム = null;
+
private bool _ループ再生する = false;
+
private System.Threading.Tasks.Task _デコードタスク = null;
+
private System.Threading.AutoResetEvent _デコードタスク起動完了 = null;
+
private System.Threading.ManualResetEvent _キューが空いた = null;
+
private System.Threading.AutoResetEvent _デコードタスクを終了せよ = null;
+
private SharpDX.MediaFoundation.SourceReaderEx _SourceReaderEx = null;
+
private SharpDX.MediaFoundation.MediaType _MediaType = null;
+
private SharpDX.WIC.Bitmap _WicBitmap = null; // MediaFoundation は WICBitmap に出力する。
+
private SharpDX.Direct2D1.DeviceContext1 _デコードタスク用D2DDeviceContext参照 = null; // D2Dはスレッドセーフであること。
private void _キューをクリアする()
} );
}
+
// 以下、デコードタスク用。
private FDK.同期.RWLock<FDK.カウンタ.QPCTimer> _再生タイマ = new 同期.RWLock<カウンタ.QPCTimer>();
}
private string _前回の表示文字列 = null;
+
private SharpDX.DirectWrite.TextFormat _テキストフォーマット = null;
+
private SharpDX.DirectWrite.TextLayout _テキストレイアウト = null;
+
private SharpDX.Direct2D1.SolidColorBrush _白ブラシ = null;
+
private SharpDX.Direct2D1.SolidColorBrush _黒ブラシ = null;
}
}
}
protected string 画像ファイルパス = null;
+
protected SharpDX.Direct2D1.Bitmap1 Bitmap = null;
protected void 画像を生成する( FDK.メディア.デバイスリソース dr, SharpDX.Direct2D1.BitmapProperties1 bitmapProperties1 = null )
}
private FDK.メディア.画像 _文字盤 = null;
+
private FDK.メディア.矩形リスト _文字矩形リスト = null;
}
}
}
private const int _デバイスの入力バッファサイズ = 32;
+
private SharpDX.DirectInput.Keyboard _Device = null; // キーボードがアタッチされていない場合は null 。
+
private IntPtr _Window = IntPtr.Zero;
+
/// <summary>
/// ポーリングごとに累積更新された最終の結果。
/// </summary>
private readonly bool[] _現在のキーの押下状態 = new bool[ 256 ];
+
private readonly List<InputEvent> _入力イベントリスト = new List<InputEvent>();
}
}
}
private List<MIDIINHANDLE> _MIDI入力デバイスハンドルリスト = null;
+
private List<InputEvent> _蓄積用入力イベントリスト = null; // コールバック関数で蓄積され、ポーリング時にキャッシュへコピー&クリアされる。
+
private List<InputEvent> _入力イベントリストキャッシュ = null; // ポーリング時のキャッシュ。
+
private MidiInProc _midiInProc = null; // 全MIDI入力デバイスで共通のコールバックのデリゲートとGCHandleと本体メソッド。
+
private System.Runtime.InteropServices.GCHandle _midiInProcGCh;
+
private readonly object _コールバック同期 = new object();
#region " Win32 API "
}
private SharpDX.MediaFoundation.DXGIDeviceManager _DeviceManager = null;
+
private IntPtr _DeviceHandle = IntPtr.Zero;
/// <param name="d3dDevice">
}
private T _Value = default( T );
+
private readonly ReaderWriterLockSlim _スレッド間同期;
}
}
}
private 状態種別 _状態 = 状態種別.OFF;
+
private ManualResetEvent _無効イベント = null;
+
private ManualResetEvent _ONイベント = null;
+
private ManualResetEvent _OFFイベント = null;
+
private readonly object _スレッド間同期 = new object();
}
}
StrokeStyleT.MIDI入力?.ポーリングする();
}
-
static StrokeStyleT()
{
// フォルダ変数を真っ先に登録する。(ほかのメンバのコンストラクタでフォルダ変数を利用できるようにするため。)
this._MainForm = new RenderForm();
this._MainForm.BackColor = System.Drawing.Color.Black;
this._MainForm.AllowUserResizing = false; // ユーザはフォームサイズを変更できない。
- this._MainForm.UserResized += フォームサイズが変更された;
+ this._MainForm.UserResized += _フォームサイズが変更された;
this._MainForm.FormClosing += ( sender, e ) => {
- this.終了する();
+ this._終了する();
};
}
switch( this._State )
{
case ApplicationState.起動:
- this.起動する();
+ this._起動する();
this._State = ApplicationState.初期化;
break; // 初期化に移る前に、一度ウィンドウメッセージ処理を行わせて、画面を再描画させる。
case ApplicationState.初期化:
- this.初期化する();
+ this._初期化する();
this._State = ApplicationState.進行描画;
break;
case ApplicationState.進行描画:
- this.進行描画する();
+ this._進行描画する();
if( this._State == ApplicationState.終了 )
- this.終了する();
+ this._終了する();
break;
case ApplicationState.終了:
#endregion
private enum ApplicationState { 起動, 初期化, 進行描画, 終了 }
+
private ApplicationState _State;
+
private SST.RenderForm _MainForm = null;
+
private SharpDX.Size2F _設計画面サイズdpx = SharpDX.Size2F.Empty;
+
private ConcurrentQueue<ViewerMessage> _ビュアーメッセージキュー = new ConcurrentQueue<ViewerMessage>();
+
private FDK.メディア.デバイスリソース _デバイスリソース = null;
+
private SST.ステージ.ステージ _最初のダミーステージ = null;
+
private SST.ステージ.起動.起動ステージ _起動ステージ = null;
+
private SST.ステージ.タイトル.タイトルステージ _タイトルステージ = null;
+
private SST.ステージ.ログイン.ログインステージ _ログインステージ = null;
+
private SST.ステージ.選曲.選曲ステージ _選曲ステージ = null;
+
private SST.ステージ.曲読込.曲読込ステージ _曲読込ステージ = null;
+
private SST.ステージ.演奏.演奏ステージ _演奏ステージ = null;
+
private SST.ステージ.結果.結果ステージ _結果ステージ = null;
+
private SST.ステージ.ステージ _現在のステージ = null;
+
private static SST.フォルダ _フォルダ = null;
+
private static FDK.入力.Keyboard _キーボード入力 = null;
+
private static FDK.入力.MidiIn _MIDI入力 = null;
+
private static FDK.メディア.サウンド.WASAPI.Device _サウンドデバイス = null;
+
private static readonly System.Random _乱数 = new Random( DateTime.Now.Millisecond );
+
private static SST.ユーザ.ユーザ管理 _ユーザ管理 = null;
+
private static SST.曲.曲ツリー管理 _曲ツリー管理 = null;
+
private static SST.設定.Config _Config = null;
- private void 起動する()
+ private void _起動する()
{
FDK.Log.現在のスレッドに名前をつける( "Render" );
FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
- private void 初期化する()
+ private void _初期化する()
{
FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
// F11 → 画面モードの切り替え
if( arg.KeyCode == System.Windows.Forms.Keys.F11 )
{
- this.全画面モードとウィンドウモードを切り替える();
+ this._全画面モードとウィンドウモードを切り替える();
arg.Handled = true;
}
};
FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
- private void 終了する()
+ private void _終了する()
{
FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
Debug.Assert( null != this._デバイスリソース, "デバイスリソースが解放される前であること。" );
this._選曲ステージ = null;
this._曲読込ステージ = null;
this._演奏ステージ.BGMを停止する();
- this._演奏ステージ?.BGMのキャッシュを解放する(); // BGMのキャッシュ(デコード済み WaveSrouce)を解放。
+ this._演奏ステージ?.BGMのキャッシュを解放する(); // BGMのキャッシュ(デコード済み WaveSource)を解放。
this._演奏ステージ = null;
this._結果ステージ = null;
//----------------
FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
- private void 進行描画する()
+ private void _進行描画する()
{
#region " D3Dデバイスが消失していれば再構築する。"
//----------------
{
// ビュアー用ユーザでログインする。
FDK.Log.Info( "ビュアーモード: AutoPlayer ユーザでログインします。" );
- this.ログインする( Properties.Resources.AUTOPLAYER );
+ this._ログインする( Properties.Resources.AUTOPLAYER );
// 曲読込ステージ向けの初期設定。
StrokeStyleT.曲ツリー管理.現在の管理対象ツリー = null;
#region " ビュアーメッセージがあれば処理する。"
//----------------
- var msg = this.ビュアーメッセージを取得する();
+ var msg = this._ビュアーメッセージを取得する();
StrokeStyleT.最後に取得したビュアーメッセージ = msg; // 保存する。(演奏ステージに対して公開する)
#endregion
}
- private void デバイス依存リソースを解放する()
+ private void _デバイス依存リソースを解放する()
{
FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
Debug.Assert( null != this._デバイスリソース ); // 解放前であること。
FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
- private void デバイス依存リソースを再構築する()
+ private void _デバイス依存リソースを再構築する()
{
FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
Debug.Assert( null != this._デバイスリソース ); // 再生成済みであること。
FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
- private void フォームサイズが変更された( object sender, EventArgs e )
+ private void _フォームサイズが変更された( object sender, EventArgs e )
{
FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
FDK.Log.Info( $"新しいクライアントサイズ = {this._MainForm.ClientSize}" );
FDK.Log.Info( $"現在、全画面モードである = {this._MainForm.IsFullscreen}" );
// (1) リソースを解放して、
- this.デバイス依存リソースを解放する();
+ this._デバイス依存リソースを解放する();
this._デバイスリソース.サイズに依存するリソースを解放する();
// (2) 物理画面サイズを変更して、
// (3) リソースを再構築する。
this._デバイスリソース.サイズに依存するリソースを作成する();
- this.デバイス依存リソースを再構築する();
+ this._デバイス依存リソースを再構築する();
FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
- private void 全画面モードとウィンドウモードを切り替える()
+ private void _全画面モードとウィンドウモードを切り替える()
{
FDK.Log.BeginInfo( $"{FDK.Utilities.現在のメソッド名}" );
FDK.Log.EndInfo( $"{FDK.Utilities.現在のメソッド名}" );
}
- private void ログインする( string ユーザ名 )
+ private void _ログインする( string ユーザ名 )
{
StrokeStyleT.ユーザ管理.ユーザを選択する( ユーザ名 );
FDK.Log.Info( $"ユーザが選択されました。[{StrokeStyleT.ユーザ管理.現在選択されているユーザ.名前}]" );
/// <returns>
/// メッセージがない場合は null を返す。
/// </returns>
- private ViewerMessage ビュアーメッセージを取得する()
+ private ViewerMessage _ビュアーメッセージを取得する()
{
var msg = (ViewerMessage) null;
#define MyAppName "StrokeStyle<T>"\r
#define MyAppName2 "SSTEditor"\r
#define MyAppFolderName "StrokeStyleT"\r
-#define MyAppVersion "1.2.17"\r
+#define MyAppVersion "1.18"\r
#define MyAppPublisher "\82\82Ü\82©\82Ý\8dH\96["\r
#define MyAppExeName "StrokeStyleT.exe"\r
#define MyAppExeName2 "SSTFEditor.exe"\r
; setup \83t\83@\83C\83\8b\96¼\81B\r
OutputBaseFilename=sstsetup-{#MyAppVersion}\r
; \83A\83v\83\8a\96¼\81B\r
-AppName={#MyAppName}\r; \83A\83v\83\8a\82Ì\83o\81[\83W\83\87\83\93\81B\81i\83R\83\93\83g\83\8d\81[\83\8b\83p\83l\83\8b\97p\81j\r
+AppName={#MyAppName}\r
+; \83A\83v\83\8a\82Ì\83o\81[\83W\83\87\83\93\81B\81i\83R\83\93\83g\83\8d\81[\83\8b\83p\83l\83\8b\97p\81j\r
AppVersion={#MyAppVersion}\r
; \83A\83v\83\8a\96¼\81{\83o\81[\83W\83\87\83\93\81B\r
AppVerName={#MyAppName} {#MyAppVersion}\r
; \83A\83v\83\8a\82Ì\94z\95z\8c³\81B(\83R\83\93\83g\83\8d\81[\83\8b\83p\83l\83\8b\97p\81j\r
-AppPublisher={#MyAppPublisher}\r; \83A\83v\83\8a\82Ì\94z\95z\8c³Web\83T\83C\83g\82ÌURL\81B\81i\83R\83\93\83g\83\8d\81[\83\8b\83p\83l\83\8b\97p\81j\r
+AppPublisher={#MyAppPublisher}\r
+; \83A\83v\83\8a\82Ì\94z\95z\8c³Web\83T\83C\83g\82ÌURL\81B\81i\83R\83\93\83g\83\8d\81[\83\8b\83p\83l\83\8b\97p\81j\r
;AppPublisherURL=\r
; \8eg\97p\8b\96\91ø\r
LicenseFile=Licence.txt\r
-; \83p\83X\83\8f\81[\83h\r;Password=\r
+; \83p\83X\83\8f\81[\83h\r
+;Password=\r
; \83C\83\93\83X\83g\81[\83\8b\82Ì\8eÀ\8ds\91O\82É\95\\8e¦\82·\82é\8fî\95ñ\81B\r
;InfoBeforeFile=\r
; \83\86\81[\83U\8fî\95ñ\82Ì\93ü\97Í\89æ\96Ê\82ð\8fo\82·\81H\r
DisableReadyPage=no\r
; \83C\83\93\83X\83g\81[\83\8b\82Ì\8eÀ\8ds\8cã\82É\95\\8e¦\82·\82é\8fî\95ñ\81B\r
;InfoAfterFile=\r
-; \81u\83Z\83b\83g\83A\83b\83v\82ª\8fI\97¹\82µ\82Ü\82µ\82½\81v\89æ\96Ê\82ð\8fo\82³\82È\82¢\81H\rDisableFinishedPage=no\r
+; \81u\83Z\83b\83g\83A\83b\83v\82ª\8fI\97¹\82µ\82Ü\82µ\82½\81v\89æ\96Ê\82ð\8fo\82³\82È\82¢\81H\r
+DisableFinishedPage=no\r
; \88³\8fk\8c`\8e®\81B\r
Compression=lzma2/max\r
SolidCompression=yes\r
Source: "{#MyAppBin}\StrokeStyleT.exe"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs\r
;Source: "{#MyAppBin}\StrokeStyleT.exe.config"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs\r
Source: "{#MyAppBin}\SSTFEditor.exe"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs\r
+Source: "{#MyAppBin}\ja-JP\*"; DestDir: "{app}\ja-JP"; Flags: ignoreversion recursesubdirs\r
Source: "{#MyAppBin}\images\*"; DestDir: "{app}\images"; Flags: ignoreversion recursesubdirs\r
Source: "{#MyAppBin}\sounds\*"; DestDir: "{app}\sounds"; Flags: ignoreversion recursesubdirs\r
Source: "{#MyAppBin}\songs\*"; DestDir: "{app}\songs"; Flags: ignoreversion recursesubdirs\r
}
private float _ハイハットの開度 = 1.0f;
+
private FDK.メディア.画像 _HiHatTop;
+
private FDK.メディア.画像 _HiHatBottom;
+
private FDK.メディア.画像 _Snare;
+
private FDK.メディア.画像 _Bass;
+
private FDK.メディア.画像 _HiTom;
+
private FDK.メディア.画像 _LowTom;
+
private FDK.メディア.画像 _FloorTom;
+
private FDK.メディア.画像 _LCymbal;
+
private FDK.メディア.画像 _LCymbalStand;
+
private FDK.メディア.画像 _LCymbalTop;
+
private FDK.メディア.画像 _RCymbal;
+
private FDK.メディア.画像 _RCymbalStand;
+
private FDK.メディア.画像 _RCymbalTop;
}
}
}
private float _総フェード時間sec = 1.0f;
+
private FDK.カウンタ.単純増加後不変カウンタ _透明度カウンタ = new FDK.カウンタ.単純増加後不変カウンタ();
}
}
}
private float _総フェード時間sec = 1.0f;
+
private FDK.カウンタ.単純増加後不変カウンタ _透明度カウンタ = new FDK.カウンタ.単純増加後不変カウンタ();
}
}
}
private List<FDK.メディア.文字列画像> _ユーザパネル = null;
+
private FDK.メディア.文字列画像 _ログイン画面見出し = null;
}
}
}
private const float _ドラムコンボの文字間隔 = 2f;
+
private const int _表示可能な最小コンボ数 = 11;
private EMode _現在のモード;
+
private int _前回のCOMBO値 = 0;
+
private long _コンボが切れた時刻 = FDK.カウンタ.QPCTimer.未使用;
+
private int _コンボが切れたときのCOMBO値 = 0;
+
private コンボジャンプ _単位付き数値 = null;
+
private ReaderWriterLockSlim スレッド間同期 = null;
}
}
}
private int _現在の数値 = -1;
+
private FDK.メディア.画像 _数値と単位の画像 = null;
+
private readonly List<SharpDX.RectangleF> _文字矩形dpx = new List<SharpDX.RectangleF>() {
#region " [0]~[9]: '0'~'9', [10]:'COMBO' "
//----------------
//----------------
#endregion
};
+
private const int _桁ごとのジャンプの遅れ = 50; // 1桁につき 50 インデックス遅れる
+
private const float _不透明度0to1 = 0.7f;
+
private int _ジャンプインデックス値 = 9999;
+
private int[] _ジャンプ差分値 = new int[ 180 ];
+
private FDK.カウンタ.定間隔進行 _ジャンプインデックス進行 = null;
+
private System.Threading.ReaderWriterLockSlim _スレッド間同期 = null;
}
}
}
private bool _活性化した直後である = false;
+
/// <summary>
/// 演奏スコア.チップリスト[] のうち、描画を始めるチップのインデックス番号を示す。
/// 演奏開始直後は 0 で始まり、対象番号のチップが描画範囲を流れ去るたびに +1 される。
/// 未演奏時・演奏終了時は -1 。
/// </summary>
private int _描画開始チップ番号 = -1;
+
private FDK.メディア.画像 _チップ画像 = null;
+
private FDK.メディア.矩形リスト _チップ画像の矩形リスト = null;
+
private Dictionary<SSTFormat.チップ種別, ヒットレーン種別> _ヒット判定を行うチップと対応するレーン = null;
+
private FDK.カウンタ.単純増加後反復カウンタ _チップアニメ = new FDK.カウンタ.単純増加後反復カウンタ();
+
private readonly Dictionary<SSTFormat.レーン種別, float> _レーン種別toレーンフレーム左端からの相対X位置dpx = new Dictionary<SSTFormat.レーン種別, float>() {
{ SSTFormat.レーン種別.LeftCrash, +36f },
{ SSTFormat.レーン種別.HiHat, +105f },
{ SSTFormat.レーン種別.Tom3, +544f },
{ SSTFormat.レーン種別.RightCrash, +632f },
};
+
private float _画面の高さdpx = 0f; // 進行スレッドからはデバイスリソースを参照しないので、ここにキャッシュしておく。
+
private FDK.同期.TriStateEvent _高頻度進行タスクへのイベント = null;
+
private readonly object _スレッド間同期 = new object();
private void _画面内に収まるチップをすべて進行描画する( デバイスリソース dr, Action<デバイスリソース, SSTFormat.チップ, float> 描画アクション, double 現在の演奏時刻sec )
}
private const int _多重度 = 2;
+
private class Cコンテキスト : IDisposable
{
public FDK.メディア.サウンド.WASAPI.Sound[] Sounds = new FDK.メディア.サウンド.WASAPI.Sound[ ドラムサウンド._多重度 ];
}
}
};
+
private Dictionary<SSTFormat.チップ種別, Cコンテキスト> _チップtoコンテキスト = null;
+
private readonly string _KitXmlファイルパス = @"$(Static)\sounds\Kit.xml";
+
private readonly object _スレッド間同期 = new object();
private void _すべてのコンテキストを初期化する()
this.透明度0to1 = 1.0f;
}
}
+
private Dictionary<ヒットレーン種別, 進行描画コンテキスト> _ヒット判定レーンto進行描画コンテキスト = null;
+
private readonly Dictionary<ヒット判定種別, FDK.メディア.画像> _文字列画像 = new Dictionary<ヒット判定種別, 画像>() {
{ ヒット判定種別.PERFECT, new 画像( @"$(Static)\images\Judge Perfect.png" ) },
{ ヒット判定種別.GREAT, new 画像( @"$(Static)\images\Judge Great.png" ) },
{ ヒット判定種別.MISS, new 画像( @"$(Static)\images\Judge Miss.png" ) },
{ ヒット判定種別.AUTO, new 画像( @"$(Static)\images\Judge Auto.png" ) },
};
+
private readonly object _スレッド間同期 = new object();
}
}
public float サイズ;
public FDK.カウンタ.単純増加後不変カウンタ 進行カウンタ;
}
+
private コンテキスト[] _コンテキスト = null;
+
private FDK.メディア.画像 _羽画像 = null;
+
private readonly object _スレッド間同期 = new object();
}
}
}
private bool _活性化した直後である = false;
+
private double _演奏開始時刻sec = 0.0;
+
private bool _Autoチップのドラム音を再生する = true;
+
private readonly SST.ステージ.演奏.コンボ _コンボ;
+
private readonly SST.ステージ.演奏.レーンフレーム _レーンフレーム;
+
private readonly SST.ステージ.演奏.スクロール譜面 _スクロール譜面;
+
private readonly SST.ステージ.演奏.ヒット判定文字列 _ヒット判定文字列;
+
private readonly SST.ステージ.演奏.回転羽 _回転羽 = new 回転羽( 32 );
+
private readonly SST.ステージ.演奏.ドラムサウンド _ドラムサウンド;
+
private readonly SST.ステージ.ドラムセット _ドラムセット;
+
private readonly FDK.メディア.画像 _判定バー;
+
private readonly FDK.メディア.画像 _ステージ台;
+
private readonly FDK.メディア.文字列画像 _FPS画像;
+
private FDK.同期.RWLock<bool> _背景動画開始済み = new FDK.同期.RWLock<bool>( false );
+
private bool _BGM再生開始済み = false;
+
private FDK.同期.RWLock<double> _現在進行描画中の譜面スクロール速度の倍率 = new FDK.同期.RWLock<double>( 0.0 );
+
/// <remarks>
/// 停止と解放は、演奏ステージクラスの非活性化後に、外部から行われる。
/// <see cref="SST.ステージ.演奏.演奏ステージ.BGMを停止する"/>
/// <see cref="SST.ステージ.演奏.演奏ステージ.BGMのキャッシュを解放する"/>
/// </remarks>
private FDK.メディア.サウンド.WASAPI.Sound _BGM = null;
+
/// <summary>
/// BGM の生成もとになるデコード済みサウンドデータ。
/// </summary>
/// 演奏ステージインスタンスを破棄する際に、このインスタンスもDisposeすること。
/// </remarks>
private FDK.メディア.サウンド.WASAPI.DecodedWaveSource _デコード済みWaveSource = null;
+
private FDK.メディア.動画 _背景動画 = null;
+
private FDK.カウンタ.FPS _FPS = null;
private double _現在の演奏時刻secを返す()
}
private bool _活性化した直後である = false;
+
private FDK.メディア.動画 _背景動画;
+
private FDK.メディア.画像 _背景画像;
+
private FDK.メディア.画像 _結果表示パラメータパネル;
+
private FDK.メディア.画像フォント _結果表示パラメータ;
}
}
}
private FDK.カウンタ.単純増加後不変カウンタ _フェーズカウンタ = null;
+
private readonly FDK.メディア.画像 _背景画像;
+
private readonly FDK.メディア.画像 _フェードインアウト兼用パネル;
+
private readonly SST.ステージ.フェードイン _フェードイン;
+
private readonly SST.ステージ.フェードアウト _フェードアウト;
}
}
}
else
{
- this.パネルを一枚描画する( dr, 描画する曲, パネル位置, これはカーソル位置のパネルである: false );
+ this._パネルを一枚描画する( dr, 描画する曲, パネル位置, これはカーソル位置のパネルである: false );
}
// 次のノードへ移動。(選択ノードは移動しない。)
if( ( 0 <= this._カーソル位置.X ) && ( 9 > this._カーソル位置.X ) &&
( 0 <= this._カーソル位置.Y ) && ( 3 > this._カーソル位置.Y ) )
{
- this.パネルを一枚描画する(
+ this._パネルを一枚描画する(
dr,
カーソル位置の曲, // 先の for ループ内で取得済み。
this._カーソル位置,
}
private const float _カーソル位置のパネルの拡大率 = 1.25f;
+
private bool _活性化した直後である = false;
+
private FDK.メディア.テクスチャ _Nullパネルの画像;
+
private FDK.カウンタ.定間隔進行 _横スクロール用カウンタ = null;
+
/// <summary>
/// 左上隅のパネルを (0,0) とした時の、カーソル位置の座標。
/// 負数も可。
/// </summary>
private SharpDX.Point _カーソル位置 = new SharpDX.Point( 4, 1 );
+
/// <summary>
/// -63~63。パネル全体の表示位置を、負数は 左 へ、正数は 右 へずらす 。(正負と左右の対応に注意。)
/// </summary>
/// <param name="パネルノード">
/// null 可。
/// </param>
- private void パネルを一枚描画する( デバイスリソース dr, 曲.Node パネルノード, SharpDX.Point パネル位置, bool これはカーソル位置のパネルである = false )
+ private void _パネルを一枚描画する( デバイスリソース dr, 曲.Node パネルノード, SharpDX.Point パネル位置, bool これはカーソル位置のパネルである = false )
{
// 画面を見ながら直観的に調整した固定パラメータたち。
const float 見かけの倍率 = 3.0f;
}
private bool _活性化した直後である = false;
+
private FDK.メディア.動画 _背景動画 = null;
+
private FDK.メディア.画像 _ステージ台 = null;
+
private SST.ステージ.ドラムセット _ドラムセット = null;
+
private 曲パネルビュー _曲パネルビュー = null;
}
}
}
private FDK.メディア.テクスチャ _サムネイル画像 = null;
+
private readonly string[] _対応する動画の拡張子 = { ".mp4", ".avi" };
+
private readonly string[] _対応するサムネイル画像名 = { "thumb.png", "thumb.bmp", "thumb.jpg", "thumb.jpeg" };
}
}
}
private タイトルテクスチャ _タイトル文画像 = null;
+
private static FDK.メディア.テクスチャ _既定の曲画像 = null; // 全インスタンスで共有
}
}
protected override void Onデバイス依存リソースの作成( デバイスリソース dr )
{
- this.テクスチャを更新する( dr );
+ this._テクスチャを更新する( dr );
}
protected override void Onデバイス依存リソースの解放( デバイスリソース dr )
// 表示文字列が変更されているなら、ここで表示ビットマップの再構築を行う。
if( false == string.Equals( this.表示文字列, this._前回の表示文字列 ) )
- this.テクスチャを更新する( dr );
+ this._テクスチャを更新する( dr );
// テクスチャを描画する。
base.描画する( dr, ワールド行列変換, 転送元矩形 );
}
private float _フォントサイズpt = 30.0f;
+
private string _フォント名 = "メイリオ";
+
private string _前回の表示文字列 = null;
+
private SharpDX.DirectWrite.TextFormat _テキストフォーマット = null;
+
private SharpDX.DirectWrite.TextLayout _テキストレイアウト = null;
+
private SharpDX.Direct2D1.SolidColorBrush _白ブラシ = null;
+
private SharpDX.Direct2D1.SolidColorBrush _黒ブラシ = null;
- private void テクスチャを更新する( デバイスリソース dr )
+ private void _テクスチャを更新する( デバイスリソース dr )
{
this._前回の表示文字列 = this.表示文字列;