1
0
mirror of synced 2024-12-20 03:15:55 +01:00
OpenTaiko/FDK19/コード/02.入力/CInputKeyboard.cs

297 lines
9.8 KiB
C#
Raw Normal View History

2021-09-21 00:16:38 +02:00
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using SharpDX;
using SharpDX.DirectInput;
using SlimDXKey = SlimDXKeys.Key;
using SharpDXKey = SharpDX.DirectInput.Key;
namespace FDK
{
public class CInputKeyboard : IInputDevice, IDisposable
{
// コンストラクタ
public CInputKeyboard(IntPtr hWnd, DirectInput directInput)
{
this.e入力デバイス種別 = E入力デバイス種別.Keyboard;
this.GUID = "";
this.ID = 0;
try
{
this.devKeyboard = new Keyboard(directInput);
this.devKeyboard.SetCooperativeLevel(hWnd, CooperativeLevel.NoWinKey | CooperativeLevel.Foreground | CooperativeLevel.NonExclusive);
this.devKeyboard.Properties.BufferSize = 32;
Trace.TraceInformation(this.devKeyboard.Information.ProductName.Trim(new char[] { '\0' }) + " を生成しました。"); // なぜか0x00のゴミが出るので削除
this.strDeviceName = this.devKeyboard.Information.ProductName.Trim(new char[] { '\0' });
}
catch
{
if(this.devKeyboard != null)
{
this.devKeyboard.Dispose();
this.devKeyboard = null;
}
Trace.TraceWarning("Keyboard デバイスの生成に失敗しました。");
throw;
}
try
{
this.devKeyboard.Acquire();
}
catch
{
}
for (int i = 0; i < this.bKeyState.Length; i++)
this.bKeyState[i] = false;
//this.timer = new CTimer( CTimer.E種別.MultiMedia );
this.list入力イベント = new List<STInputEvent>(32);
// this.ct = new CTimer( CTimer.E種別.PerformanceCounter );
}
// メソッド
#region [ IInputDevice ]
//-----------------
public E入力デバイス種別 e入力デバイス種別 { get; private set; }
public string GUID { get; private set; }
public int ID { get; private set; }
public List<STInputEvent> list入力イベント { get; private set; }
public string strDeviceName { get; set; }
public void tポーリング(bool bWindowがアクティブ中, bool bバッファ入力を使用する)
{
for (int i = 0; i < 256; i++)
{
this.bKeyPushDown[i] = false;
this.bKeyPullUp[i] = false;
}
if (bWindowがアクティブ中 && (this.devKeyboard != null))
{
this.devKeyboard.Acquire();
this.devKeyboard.Poll();
//this.list入力イベント = new List<STInputEvent>( 32 );
this.list入力イベント.Clear(); // #xxxxx 2012.6.11 yyagi; To optimize, I removed new();
int posEnter = -1;
//string d = DateTime.Now.ToString( "yyyy/MM/dd HH:mm:ss.ffff" );
if (bバッファ入力を使用する)
{
#region [ a. ]
//-----------------------------
var bufferedData = this.devKeyboard.GetBufferedData();
//if ( Result.Last.IsSuccess && bufferedData != null )
{
foreach (KeyboardUpdate data in bufferedData)
{
// #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
var key = DeviceConstantConverter.DIKtoKey(data.Key);
if (SlimDXKey.Unknown == key)
continue; // 未対応キーは無視。
//foreach ( Key key in data.PressedKeys )
if (data.IsPressed)
{
// #23708 2016.3.19 yyagi; Even if we remove ALT+ENTER key input by SuppressKeyPress = true in Form,
// it doesn't affect to DirectInput (ALT+ENTER does not remove)
// So we ignore ENTER input in ALT+ENTER combination here.
// Note: ENTER will be alived if you keyup ALT after ALT+ENTER.
if (key != SlimDXKey.Return || (bKeyState[(int)SlimDXKey.LeftAlt] == false && bKeyState[(int)SlimDXKey.RightAlt] == false))
{
STInputEvent item = new STInputEvent()
{
nKey = (int)key,
b押された = true,
b離された = false,
nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換(data.Timestamp),
nVelocity = CInput管理.n通常音量
};
this.list入力イベント.Add(item);
this.bKeyState[(int)key] = true;
this.bKeyPushDown[(int)key] = true;
}
//if ( item.nKey == (int) SlimDXKey.Space )
//{
// Trace.TraceInformation( "FDK(buffered): SPACE key registered. " + ct.nシステム時刻 );
//}
}
//foreach ( Key key in data.ReleasedKeys )
if (data.IsReleased)
{
STInputEvent item = new STInputEvent()
{
nKey = (int)key,
b押された = false,
b離された = true,
nTimeStamp = CSound管理.rc演奏用タイマ.nサウンドタイマーのシステム時刻msへの変換(data.Timestamp),
nVelocity = CInput管理.n通常音量
};
this.list入力イベント.Add(item);
this.bKeyState[(int)key] = false;
this.bKeyPullUp[(int)key] = true;
}
}
}
//-----------------------------
#endregion
}
else
{
#region [ b. ]
//-----------------------------
KeyboardState currentState = this.devKeyboard.GetCurrentState();
//if ( Result.Last.IsSuccess && currentState != null )
{
foreach (SharpDXKey dik in currentState.PressedKeys)
{
// #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
var key = DeviceConstantConverter.DIKtoKey(dik);
if (SlimDXKey.Unknown == key)
continue; // 未対応キーは無視。
if (this.bKeyState[(int)key] == false)
{
if (key != SlimDXKey.Return || (bKeyState[(int)SlimDXKey.LeftAlt] == false && bKeyState[(int)SlimDXKey.RightAlt] == false)) // #23708 2016.3.19 yyagi
{
var ev = new STInputEvent()
{
nKey = (int)key,
b押された = true,
b離された = false,
nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
nVelocity = CInput管理.n通常音量,
};
this.list入力イベント.Add(ev);
this.bKeyState[(int)key] = true;
this.bKeyPushDown[(int)key] = true;
}
//if ( (int) key == (int) SlimDXKey.Space )
//{
// Trace.TraceInformation( "FDK(direct): SPACE key registered. " + ct.nシステム時刻 );
//}
}
}
//foreach ( Key key in currentState.ReleasedKeys )
foreach (SharpDXKey dik in currentState.AllKeys)
{
// #xxxxx: 2017.5.7: from: DIK (SharpDX.DirectInput.Key) を SlimDX.DirectInput.Key に変換。
var key = DeviceConstantConverter.DIKtoKey(dik);
if (SlimDXKey.Unknown == key)
continue; // 未対応キーは無視。
if (this.bKeyState[(int)key] == true && !currentState.IsPressed(dik)) // 前回は押されているのに今回は押されていない → 離された
{
var ev = new STInputEvent()
{
nKey = (int)key,
b押された = false,
b離された = true,
nTimeStamp = CSound管理.rc演奏用タイマ.nシステム時刻, // 演奏用タイマと同じタイマを使うことで、BGMと譜面、入力ずれを防ぐ。
nVelocity = CInput管理.n通常音量,
};
this.list入力イベント.Add(ev);
this.bKeyState[(int) key] = false;
this.bKeyPullUp[(int) key] = true;
}
}
}
//-----------------------------
#endregion
}
#region [#23708 2011.4.8 yyagi Altが押されているときはEnter押下情報を削除する -> ]
//if ( this.bKeyState[ (int) SlimDXKey.RightAlt ] ||
// this.bKeyState[ (int) SlimDXKey.LeftAlt ] )
//{
// int cr = (int) SlimDXKey.Return;
// this.bKeyPushDown[ cr ] = false;
// this.bKeyPullUp[ cr ] = false;
// this.bKeyState[ cr ] = false;
//}
#endregion
}
}
/// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param>
public bool bキーが押された(int nKey)
{
return this.bKeyPushDown[nKey];
}
/// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param>
public bool bキーが押されている(int nKey)
{
return this.bKeyState[ nKey ];
}
/// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param>
public bool bキーが離された(int nKey)
{
return this.bKeyPullUp[nKey];
}
/// <param name="nKey">
/// 調べる SlimDX.DirectInput.Key を int にキャストした値。SharpDX.DirectInput.Key ではないので注意。)
/// </param>
public bool bキーが離されている(int nKey)
{
return !this.bKeyState[nKey];
}
//-----------------
#endregion
#region [ IDisposable ]
//-----------------
public void Dispose()
{
if(!this.bDispose完了済み)
{
if(this.devKeyboard != null)
{
this.devKeyboard.Dispose();
this.devKeyboard = null;
}
//if( this.timer != null )
//{
// this.timer.Dispose();
// this.timer = null;
//}
if (this.list入力イベント != null)
{
this.list入力イベント = null;
}
this.bDispose完了済み = true;
}
}
//-----------------
#endregion
// その他
#region [ private ]
//-----------------
private bool[] bKeyPullUp = new bool[256];
private bool[] bKeyPushDown = new bool[256];
private bool[] bKeyState = new bool[256];
private bool bDispose完了済み;
private Keyboard devKeyboard;
//private CTimer timer;
//private CTimer ct;
//-----------------
#endregion
}
}