2 using System.Collections.Generic;
\r
4 using System.Diagnostics;
\r
6 using SharpDX.DirectInput;
\r
8 using SlimDXKey = SlimDX.DirectInput.Key;
\r
9 using SharpDXKey = SharpDX.DirectInput.Key;
\r
13 public class CInputKeyboard : IInputDevice, IDisposable
\r
17 public CInputKeyboard( IntPtr hWnd, DirectInput directInput )
\r
19 this.e入力デバイス種別 = E入力デバイス種別.Keyboard;
\r
24 this.devKeyboard = new Keyboard( directInput );
\r
25 this.devKeyboard.SetCooperativeLevel( hWnd, CooperativeLevel.NoWinKey | CooperativeLevel.Foreground | CooperativeLevel.NonExclusive );
\r
26 this.devKeyboard.Properties.BufferSize = 32;
\r
27 Trace.TraceInformation( this.devKeyboard.Information.ProductName + " を生成しました。" );
\r
31 if( this.devKeyboard != null )
\r
33 this.devKeyboard.Dispose();
\r
34 this.devKeyboard = null;
\r
36 Trace.TraceWarning( "Keyboard デバイスの生成に失敗しました。" );
\r
41 this.devKeyboard.Acquire();
\r
47 for( int i = 0; i < this.bKeyState.Length; i++ )
\r
48 this.bKeyState[ i ] = false;
\r
50 //this.timer = new CTimer( CTimer.E種別.MultiMedia );
\r
51 this.list入力イベント = new List<STInputEvent>( 32 );
\r
52 // this.ct = new CTimer( CTimer.E種別.PerformanceCounter );
\r
58 #region [ IInputDevice 実装 ]
\r
60 public E入力デバイス種別 e入力デバイス種別 { get; private set; }
\r
61 public string GUID { get; private set; }
\r
62 public int ID { get; private set; }
\r
63 public List<STInputEvent> list入力イベント { get; private set; }
\r
65 public void tポーリング( bool bWindowがアクティブ中, bool bバッファ入力を使用する )
\r
67 for ( int i = 0; i < 256; i++ )
\r
69 this.bKeyPushDown[ i ] = false;
\r
70 this.bKeyPullUp[ i ] = false;
\r
73 if ( bWindowがアクティブ中 && ( this.devKeyboard != null ) )
\r
75 this.devKeyboard.Acquire();
\r
76 this.devKeyboard.Poll();
\r
78 //this.list入力イベント = new List<STInputEvent>( 32 );
\r
79 this.list入力イベント.Clear(); // #xxxxx 2012.6.11 yyagi; To optimize, I removed new();
\r
81 //string d = DateTime.Now.ToString( "yyyy/MM/dd HH:mm:ss.ffff" );
\r
85 #region [ a.バッファ入力 ]
\r
86 //-----------------------------
\r
87 var bufferedData = this.devKeyboard.GetBufferedData();
\r
88 //if ( Result.Last.IsSuccess && bufferedData != null )
\r
90 foreach( KeyboardUpdate data in bufferedData )
\r
92 // #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
\r
93 var key = DeviceConstantConverter.DIKtoKey( data.Key );
\r
94 if( SlimDXKey.Unknown == key )
\r
95 continue; // 未対応キーは無視。
\r
97 //foreach ( Key key in data.PressedKeys )
\r
98 if( data.IsPressed )
\r
100 // #23708 2016.3.19 yyagi; Even if we remove ALT+ENTER key input by SuppressKeyPress = true in Form,
\r
101 // it doesn't affect to DirectInput (ALT+ENTER does not remove)
\r
102 // So we ignore ENTER input in ALT+ENTER combination here.
\r
103 // Note: ENTER will be alived if you keyup ALT after ALT+ENTER.
\r
104 if( key != SlimDXKey.Return || ( bKeyState[ (int) SlimDXKey.LeftAlt ] == false && bKeyState[ (int) SlimDXKey.RightAlt ] == false ) )
\r
106 STInputEvent item = new STInputEvent() {
\r
110 nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換( data.Timestamp ),
\r
111 nVelocity = CInput管理.n通常音量
\r
113 this.list入力イベント.Add( item );
\r
115 this.bKeyState[ (int) key ] = true;
\r
116 this.bKeyPushDown[ (int) key ] = true;
\r
118 //if ( item.nKey == (int) SlimDXKey.Space )
\r
120 // Trace.TraceInformation( "FDK(buffered): SPACE key registered. " + ct.nシステム時刻 );
\r
123 //foreach ( Key key in data.ReleasedKeys )
\r
124 if( data.IsReleased )
\r
126 STInputEvent item = new STInputEvent() {
\r
130 nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換( data.Timestamp ),
\r
131 nVelocity = CInput管理.n通常音量
\r
133 this.list入力イベント.Add( item );
\r
135 this.bKeyState[ (int) key ] = false;
\r
136 this.bKeyPullUp[ (int) key ] = true;
\r
140 //-----------------------------
\r
146 //-----------------------------
\r
147 KeyboardState currentState = this.devKeyboard.GetCurrentState();
\r
148 //if ( Result.Last.IsSuccess && currentState != null )
\r
150 foreach( SharpDXKey dik in currentState.PressedKeys )
\r
152 // #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
\r
153 var key = DeviceConstantConverter.DIKtoKey( dik );
\r
154 if( SlimDXKey.Unknown == key )
\r
155 continue; // 未対応キーは無視。
\r
157 if( this.bKeyState[ (int) key ] == false )
\r
159 if( key != SlimDXKey.Return || ( bKeyState[ (int) SlimDXKey.LeftAlt ] == false && bKeyState[ (int) SlimDXKey.RightAlt ] == false ) ) // #23708 2016.3.19 yyagi
\r
161 var ev = new STInputEvent() {
\r
165 nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
\r
166 nVelocity = CInput管理.n通常音量,
\r
168 this.list入力イベント.Add( ev );
\r
170 this.bKeyState[ (int) key ] = true;
\r
171 this.bKeyPushDown[ (int) key ] = true;
\r
174 //if ( (int) key == (int) SlimDXKey.Space )
\r
176 // Trace.TraceInformation( "FDK(direct): SPACE key registered. " + ct.nシステム時刻 );
\r
180 //foreach ( Key key in currentState.ReleasedKeys )
\r
181 foreach( SharpDXKey dik in currentState.AllKeys )
\r
183 // #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
\r
184 var key = DeviceConstantConverter.DIKtoKey( dik );
\r
185 if( SlimDXKey.Unknown == key )
\r
186 continue; // 未対応キーは無視。
\r
188 if( this.bKeyState[ (int) key ] == true && !currentState.IsPressed( dik ) ) // 前回は押されているのに今回は押されていない → 離された
\r
190 var ev = new STInputEvent() {
\r
194 nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
\r
195 nVelocity = CInput管理.n通常音量,
\r
197 this.list入力イベント.Add( ev );
\r
199 this.bKeyState[ (int) key ] = false;
\r
200 this.bKeyPullUp[ (int) key ] = true;
\r
204 //-----------------------------
\r
207 #region [#23708 2011.4.8 yyagi Altが押されているときは、Enter押下情報を削除する -> 副作用が見つかり削除]
\r
208 //if ( this.bKeyState[ (int) SlimDXKey.RightAlt ] ||
\r
209 // this.bKeyState[ (int) SlimDXKey.LeftAlt ] )
\r
211 // int cr = (int) SlimDXKey.Return;
\r
212 // this.bKeyPushDown[ cr ] = false;
\r
213 // this.bKeyPullUp[ cr ] = false;
\r
214 // this.bKeyState[ cr ] = false;
\r
220 /// <param name="nKey">
\r
221 /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
\r
223 public bool bキーが押された( int nKey )
\r
225 return this.bKeyPushDown[ nKey ];
\r
228 /// <param name="nKey">
\r
229 /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
\r
231 public bool bキーが押されている( int nKey )
\r
233 return this.bKeyState[ nKey ];
\r
236 /// <param name="nKey">
\r
237 /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
\r
239 public bool bキーが離された( int nKey )
\r
241 return this.bKeyPullUp[ nKey ];
\r
244 /// <param name="nKey">
\r
245 /// 調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)
\r
247 public bool bキーが離されている( int nKey )
\r
249 return !this.bKeyState[ nKey ];
\r
251 //-----------------
\r
254 #region [ IDisposable 実装 ]
\r
255 //-----------------
\r
256 public void Dispose()
\r
258 if( !this.bDispose完了済み )
\r
260 if( this.devKeyboard != null )
\r
262 this.devKeyboard.Dispose();
\r
263 this.devKeyboard = null;
\r
265 //if( this.timer != null )
\r
267 // this.timer.Dispose();
\r
268 // this.timer = null;
\r
270 if ( this.list入力イベント != null )
\r
272 this.list入力イベント = null;
\r
274 this.bDispose完了済み = true;
\r
277 //-----------------
\r
283 #region [ private ]
\r
284 //-----------------
\r
285 private bool bDispose完了済み;
\r
286 private bool[] bKeyPullUp = new bool[ 256 ];
\r
287 private bool[] bKeyPushDown = new bool[ 256 ];
\r
288 private bool[] bKeyState = new bool[ 256 ];
\r
289 private Keyboard devKeyboard;
\r
290 //private CTimer timer;
\r
291 //private CTimer ct;
\r
292 //-----------------
\r