OSDN Git Service

f3dc3ea98ac066c7834f584d141fde0bf3611ac6
[dtxmania/dtxmania.git] / FDK17プロジェクト / コード / 02.入力 / CInputKeyboard.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Diagnostics;\r
5 using SharpDX;\r
6 using SharpDX.DirectInput;\r
7 \r
8 using SlimDXKey = SlimDX.DirectInput.Key;\r
9 using SharpDXKey = SharpDX.DirectInput.Key;\r
10 \r
11 namespace FDK\r
12 {\r
13         public class CInputKeyboard : IInputDevice, IDisposable\r
14         {\r
15                 // コンストラクタ\r
16 \r
17                 public CInputKeyboard( IntPtr hWnd, DirectInput directInput )\r
18                 {\r
19                         this.e入力デバイス種別 = E入力デバイス種別.Keyboard;\r
20                         this.GUID = "";\r
21                         this.ID = 0;\r
22                         try\r
23                         {\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
28                         }\r
29                         catch\r
30                         {\r
31                                 if( this.devKeyboard != null )\r
32                                 {\r
33                                         this.devKeyboard.Dispose();\r
34                                         this.devKeyboard = null;\r
35                                 }\r
36                                 Trace.TraceWarning( "Keyboard デバイスの生成に失敗しました。" );\r
37                                 throw;\r
38                         }\r
39                         try\r
40                         {\r
41                                 this.devKeyboard.Acquire();\r
42                         }\r
43                         catch\r
44                         {\r
45                         }\r
46 \r
47                         for( int i = 0; i < this.bKeyState.Length; i++ )\r
48                                 this.bKeyState[ i ] = false;\r
49 \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
53                 }\r
54 \r
55 \r
56                 // メソッド\r
57 \r
58                 #region [ IInputDevice 実装 ]\r
59                 //-----------------\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
64 \r
65                 public void tポーリング( bool bWindowがアクティブ中, bool bバッファ入力を使用する )\r
66                 {\r
67                         for ( int i = 0; i < 256; i++ )\r
68                         {\r
69                                 this.bKeyPushDown[ i ] = false;\r
70                                 this.bKeyPullUp[ i ] = false;\r
71                         }\r
72 \r
73                         if ( bWindowがアクティブ中 && ( this.devKeyboard != null ) )\r
74                         {\r
75                                 this.devKeyboard.Acquire();\r
76                                 this.devKeyboard.Poll();\r
77 \r
78                                 //this.list入力イベント = new List<STInputEvent>( 32 );\r
79                                 this.list入力イベント.Clear();                    // #xxxxx 2012.6.11 yyagi; To optimize, I removed new();\r
80                                 int posEnter = -1;\r
81                                 //string d = DateTime.Now.ToString( "yyyy/MM/dd HH:mm:ss.ffff" );\r
82 \r
83                                 if ( bバッファ入力を使用する )\r
84                                 {\r
85                                         #region [ a.バッファ入力 ]\r
86                                         //-----------------------------\r
87                                         var bufferedData = this.devKeyboard.GetBufferedData();\r
88                                         //if ( Result.Last.IsSuccess && bufferedData != null )\r
89                                         {\r
90                                                 foreach( KeyboardUpdate data in bufferedData )\r
91                                                 {\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
96 \r
97                                                         //foreach ( Key key in data.PressedKeys )\r
98                                                         if( data.IsPressed )\r
99                                                         {\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
105                                                                 {\r
106                                                                         STInputEvent item = new STInputEvent() {\r
107                                                                                 nKey = (int) key,\r
108                                                                                 b押された = true,\r
109                                                                                 b離された = false,\r
110                                                                                 nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換( data.Timestamp ),\r
111                                                                                 nVelocity = CInput管理.n通常音量\r
112                                                                         };\r
113                                                                         this.list入力イベント.Add( item );\r
114 \r
115                                                                         this.bKeyState[ (int) key ] = true;\r
116                                                                         this.bKeyPushDown[ (int) key ] = true;\r
117                                                                 }\r
118                                                                 //if ( item.nKey == (int) SlimDXKey.Space )\r
119                                                                 //{\r
120                                                                 //    Trace.TraceInformation( "FDK(buffered): SPACE key registered. " + ct.nシステム時刻 );\r
121                                                                 //}\r
122                                                         }\r
123                                                         //foreach ( Key key in data.ReleasedKeys )\r
124                                                         if( data.IsReleased )\r
125                                                         {\r
126                                                                 STInputEvent item = new STInputEvent() {\r
127                                                                         nKey = (int) key,\r
128                                                                         b押された = false,\r
129                                                                         b離された = true,\r
130                                                                         nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換( data.Timestamp ),\r
131                                                                         nVelocity = CInput管理.n通常音量\r
132                                                                 };\r
133                                                                 this.list入力イベント.Add( item );\r
134 \r
135                                                                 this.bKeyState[ (int) key ] = false;\r
136                                                                 this.bKeyPullUp[ (int) key ] = true;\r
137                                                         }\r
138                                                 }\r
139                                         }\r
140                                         //-----------------------------\r
141                                         #endregion\r
142                                 }\r
143                                 else\r
144                                 {\r
145                                         #region [ b.状態入力 ]\r
146                                         //-----------------------------\r
147                                         KeyboardState currentState = this.devKeyboard.GetCurrentState();\r
148                                         //if ( Result.Last.IsSuccess && currentState != null )\r
149                                         {\r
150                                                 foreach( SharpDXKey dik in currentState.PressedKeys )\r
151                                                 {\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
156 \r
157                                                         if( this.bKeyState[ (int) key ] == false )\r
158                                                         {\r
159                                                                 if( key != SlimDXKey.Return || ( bKeyState[ (int) SlimDXKey.LeftAlt ] == false && bKeyState[ (int) SlimDXKey.RightAlt ] == false ) )    // #23708 2016.3.19 yyagi\r
160                                                                 {\r
161                                                                         var ev = new STInputEvent() {\r
162                                                                                 nKey = (int) key,\r
163                                                                                 b押された = true,\r
164                                                                                 b離された = false,\r
165                                                                                 nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。\r
166                                                                                 nVelocity = CInput管理.n通常音量,\r
167                                                                         };\r
168                                                                         this.list入力イベント.Add( ev );\r
169 \r
170                                                                         this.bKeyState[ (int) key ] = true;\r
171                                                                         this.bKeyPushDown[ (int) key ] = true;\r
172                                                                 }\r
173 \r
174                                                                 //if ( (int) key == (int) SlimDXKey.Space )\r
175                                                                 //{\r
176                                                                 //    Trace.TraceInformation( "FDK(direct): SPACE key registered. " + ct.nシステム時刻 );\r
177                                                                 //}\r
178                                                         }\r
179                                                 }\r
180                                                 //foreach ( Key key in currentState.ReleasedKeys )\r
181                                                 foreach( SharpDXKey dik in currentState.AllKeys )\r
182                                                 {\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
187 \r
188                                                         if( this.bKeyState[ (int) key ] == true && !currentState.IsPressed( dik ) ) // 前回は押されているのに今回は押されていない → 離された\r
189                                                         {\r
190                                                                 var ev = new STInputEvent() {\r
191                                                                         nKey = (int) key,\r
192                                                                         b押された = false,\r
193                                                                         b離された = true,\r
194                                                                         nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。\r
195                                                                         nVelocity = CInput管理.n通常音量,\r
196                                                                 };\r
197                                                                 this.list入力イベント.Add( ev );\r
198 \r
199                                                                 this.bKeyState[ (int) key ] = false;\r
200                                                                 this.bKeyPullUp[ (int) key ] = true;\r
201                                                         }\r
202                                                 }\r
203                                         }\r
204                                         //-----------------------------\r
205                                         #endregion\r
206                                 }\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
210                                 //{\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
215                                 //}\r
216                                 #endregion\r
217                         }\r
218                 }\r
219 \r
220                 /// <param name="nKey">\r
221                 ///             調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)\r
222                 /// </param>\r
223                 public bool bキーが押された( int nKey )\r
224                 {\r
225                         return this.bKeyPushDown[ nKey ];\r
226                 }\r
227 \r
228                 /// <param name="nKey">\r
229                 ///             調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)\r
230                 /// </param>\r
231                 public bool bキーが押されている( int nKey )\r
232                 {\r
233                         return this.bKeyState[ nKey ];\r
234                 }\r
235 \r
236                 /// <param name="nKey">\r
237                 ///             調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)\r
238                 /// </param>\r
239                 public bool bキーが離された( int nKey )\r
240                 {\r
241                         return this.bKeyPullUp[ nKey ];\r
242                 }\r
243 \r
244                 /// <param name="nKey">\r
245                 ///             調べる SlimDX.DirectInput.Key を int にキャストした値。(SharpDX.DirectInput.Key ではないので注意。)\r
246                 /// </param>\r
247                 public bool bキーが離されている( int nKey )\r
248                 {\r
249                         return !this.bKeyState[ nKey ];\r
250                 }\r
251                 //-----------------\r
252                 #endregion\r
253 \r
254                 #region [ IDisposable 実装 ]\r
255                 //-----------------\r
256                 public void Dispose()\r
257                 {\r
258                         if( !this.bDispose完了済み )\r
259                         {\r
260                                 if( this.devKeyboard != null )\r
261                                 {\r
262                                         this.devKeyboard.Dispose();\r
263                                         this.devKeyboard = null;\r
264                                 }\r
265                                 //if( this.timer != null )\r
266                                 //{\r
267                                 //    this.timer.Dispose();\r
268                                 //    this.timer = null;\r
269                                 //}\r
270                                 if ( this.list入力イベント != null )\r
271                                 {\r
272                                         this.list入力イベント = null;\r
273                                 }\r
274                                 this.bDispose完了済み = true;\r
275                         }\r
276                 }\r
277                 //-----------------\r
278                 #endregion\r
279 \r
280 \r
281                 // その他\r
282 \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
293                 #endregion\r
294         }\r
295 }\r